我正在使用Codeigniter 4框架,我有一个控制器函数,它显示一个带有姓名、电子邮件和消息字段的表单,然后在提交时验证输入。我正在尝试使用此控制器的内置PHPUnit测试套件设置2个测试用例:一个有所有错误,一个没有错误。问题是,在我运行了有错误的第一个测试之后,第二个测试总是失败,并保存了相同的错误。我已经尝试过销毁会话,但由于测试套件使用MockSession,destroy()的工作方式似乎不一样。
以下是显示表单的函数:
public function question()
{
$items = array(
"name" => array("display" => "Your Name", "type" => "input"),
"email" => array("display" => "Your Email", "type" => "input"),
"message" => array("display" => "Message", "type" => "textarea", "rows" => 5),
);
$data = $this->getForm($items, array(), "How Can We Help?");
$this->displayView("template/form", $data);
}
以下是表单提交后验证输入、向用户显示消息并重定向回表单的函数:
public function attemptQuestion()
{
$rules = array(
"name" => array(
"rules" => "required|string|max_length[30]",
"errors" => array(
"required" => "Your name is required",
"max_length" => "Please limit to the first 30 characters in your name"
)
),
"email" => array(
"rules" => "required|valid_email|max_length[30]",
"errors" => array(
"required" => "Your email is required",
"valid_email" => "Your email is invalid",
"max_length" => "Email address is limited to 30 characters"
)
),
"message" => array(
"rules" => "required",
"errors" => array(
"required" => "Message is required"
)
),
);
if (! $this->validate($rules))
{
return redirect()->to(site_url("contact/question"))->withInput()->with("errors", $this->validator->getErrors());
}
return redirect()->to(site_url("contact/question"))->with("message", lang("Base.messageSent"));
}
下面是测试类:
namespace CodeIgniter;
use CodeIgniter\Test\CIUnitTestCase;
use CodeIgniter\Test\DatabaseTestTrait;
use CodeIgniter\Test\FilterTestTrait;
use CodeIgniter\Test\FeatureTestTrait;
class QuestionTest extends CIUnitTestCase
{
use FilterTestTrait;
public function testQuestionError()
{
$params = array(
"name" => "01234567890123456789012345678901234567", // >30 characters
"email" => "01234567890123456789012345678901234567", // >30 characters, invalid email
"message" => NULL, // empty
csrf_token() => csrf_hash()
);
$errors = array(
'name' => 'Please limit to the first 100 characters in your name',
'email' => 'Your email is invalid',
'message' => 'Message is required'
);
$this->checkIndex($params, $errors);
}
public function testQuestionSuccess()
{
$params = array(
"name" => "Joe Tester",
"email" => "joe@example.com",
"message" => "this is a test",
csrf_token() => csrf_hash()
);
$this->checkIndex($params, FALSE, lang("Base.messageSent"));
}
private function checkQuestion($parameters, $errors = FALSE, $message = FALSE)
{
// clear session
$_SESSION = [];
$result = $this->post("contact/index", $parameters);
$result->assertOK();
$result->assertRedirect();
$result->assertRedirectTo(site_url("contact/question"));
if ($errors)
{
$result->assertSessionHas('errors', $errors);
}
if ($message)
{
$result->assertSessionHas('message', $message);
}
}
}
这里有几个相关的链接供参考,但似乎仍然不能完全回答这个问题:
https://github.com/codeigniter4/CodeIgniter4/issues/3578
https://forum.codeigniter.com/thread-74701.html
更新
我已经升级到了CI4.2.0,默认情况下启用“resetServices”,这应该可以解决这个问题,但是不幸的是,我得到了同样的错误。作为参考,我尝试将$this-〉post调用 Package 在print语句中,如下所示:
file_put_contents('php://stderr', print_r($parameters, true));
$result = $this->post("contact/index", $parameters);
print_r($_SESSION);
这将产生以下结果:
evana@LAPTOP-ICCPFR27 MINGW64 /c/sites/www (master)
$ ./vendor/bin/phpunit --filter 'ContactPostTest'
PHPUnit 9.5.20 #StandWithUkraine
Warning: No code coverage driver available
Array
(
[name] => 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
[email] => 01234567890123456789012345678901234567890123456789012345678901234567890123456789089@example.com
[subject] =>
[csrfPEtoken] => 928d217bb8d905caa5783275a72347db
)
.Array
(
[_ci_old_input] => Array
(
[get] => Array
(
)
[post] => Array
(
)
)
[__ci_vars] => Array
(
[_ci_old_input] => new
[_ci_validation_errors] => new
[errors] => new
)
[_ci_validation_errors] => a:6:{s:4:"name";s:53:"Please limit to the first 100 characters in your name";s:5:"email";s:21:"Your email is invalid";s:7:"message";s:19:"Message is required";}
[errors] => Array
(
[name] => Please limit to the first 100 characters in your name
[email] => Your email is invalid
[message] => Message is required
)
)
Array
(
[name] => Evan
[email] => evan@example.com
[message] => this is a test
[csrfPEtoken] => a55091ab0a922566c44b3ede325b59cd
)
F 2 / 2 (100%)Array
(
[_ci_old_input] => Array
(
[get] => Array
(
)
[post] => Array
(
)
)
[__ci_vars] => Array
(
[_ci_old_input] => new
[_ci_validation_errors] => new
[errors] => new
)
[_ci_validation_errors] => a:6:{s:4:"name";s:53:"Please limit to the first 100 characters in your name";s:5:"email";s:21:"Your email is invalid";s:7:"message";s:19:"Message is required";}
[errors] => Array
(
[name] => Please limit to the first 100 characters in your name
[email] => Your email is invalid
[message] => Message is required
)
)
Time: 00:00.320, Memory: 16.00 MB
There was 1 failure:
1) CodeIgniter\ContactPostTest::testQuestionSuccess
'message' is not in the current $_SESSION
Failed asserting that an array has the key 'message'.
C:\sites\www\vendor\codeigniter4\framework\system\Test\TestResponse.php:255
C:\sites\www\tests\app\Controllers\ContactPostTest.php:101
C:\sites\www\tests\app\Controllers\ContactPostTest.php:67
FAILURES!
Tests: 2, Assertions: 7, Failures: 1.
1条答案
按热度按时间hc2pp10m1#
为了清除会话,您需要使用MockSession并启用resetServices。此外,为了防止对其他人有帮助,您需要在每个函数中只包含一个HTTP请求(当我扩展测试时,我将所有错误调用放在一个函数中,这也导致了会话问题)。
下面是更正后的代码: