CodeIgniter4 控制器测试

2020-08-17 17:43 更新

有了两个新的帮助程序类和特征,可以方便地测试控制器。在测试控制器时,您可以在控制器内执行代码,而无需先执行整个应用程序引导过程。通常,使用功能测试工具会更简单,但是可以在需要时使用此功能。

注解

由于尚未引导整个框架,因此有时您无法以这种方式测试控制器。

助手特质

您可以使用任何一个基础测试类,但是您确实需要ControllerTester在测试中使用特征:

  1. <?php namespace CodeIgniter;
  2. use CodeIgniter\Test\ControllerTester;
  3. class TestControllerA extends \CIDatabaseTestCase
  4. {
  5. use ControllerTester;
  6. }

一旦包含了特征,就可以开始设置环境,包括请求和响应类,请求主体,URI等。您指定要与该controller()方法一起使用的控制器,并传入控制器的标准类名。最后,execute()使用要作为参数运行的方法名称来调用该方法:

  1. <?php namespace CodeIgniter;
  2. use CodeIgniter\Test\ControllerTester;
  3. class TestControllerA extends \CIDatabaseTestCase
  4. {
  5. use ControllerTester;
  6. public function testShowCategories()
  7. {
  8. $result = $this->withURI('http://example.com/categories')
  9. ->controller(\App\Controllers\ForumController::class)
  10. ->execute('showCategories');
  11. $this->assertTrue($result->isOK());
  12. }
  13. }

辅助方法

controller($class)

指定要测试的控制器的类名。第一个参数必须是完全限定的类名称(即,包括名称空间):

  1. $this->controller(\App\Controllers\ForumController::class);

execute($method)

在控制器内执行指定的方法。唯一的参数是要运行的方法的名称:

  1. $results = $this->controller(\App\Controllers\ForumController::class)
  2. ->execute('showCategories');

这将返回一个新的帮助器类,该类提供了许多例程来检查响应本身。有关详情,请参见下文。

withConfig($config)

允许您传入ConfigApp.php的修改版本以测试不同的设置:

  1. $config = new Config\App();
  2. $config->appTimezone = 'America/Chicago';
  3. $results = $this->withConfig($config)
  4. ->controller(\App\Controllers\ForumController::class)
  5. ->execute('showCategories');

如果您不提供,则将使用应用程序的App配置文件。

withRequest($request)

允许您提供适合您的测试需求的IncomingRequest实例:

  1. $request = new CodeIgniter\HTTP\IncomingRequest(new Config\App(), new URI('http://example.com'));
  2. $request->setLocale($locale);
  3. $results = $this->withRequest($request)
  4. ->controller(\App\Controllers\ForumController::class)
  5. ->execute('showCategories');

如果不提供,则具有默认应用程序值的新IncomingRequest实例将传递到控制器中。

withResponse($response)

允许您提供一个Response实例:

  1. $response = new CodeIgniter\HTTP\Response(new Config\App());
  2. $results = $this->withResponse($response)
  3. ->controller(\App\Controllers\ForumController::class)
  4. ->execute('showCategories');

如果不提供,则具有默认应用程序值的新Response实例将传递到控制器中。

withLogger($logger)

允许您提供一个Logger实例:

  1. $logger = new CodeIgniter\Log\Handlers\FileHandler();
  2. $results = $this->withResponse($response)
  3. ->withLogger($logger)
  4. ->controller(\App\Controllers\ForumController::class)
  5. ->execute('showCategories');

如果不提供,则具有默认配置值的新Logger实例将传递到控制器中。

withURI($uri)

允许您提供一个新的URI,该URI模拟运行该控制器时客户端正在访问的URL。如果您需要检查控制器中的URI段,这将很有帮助。唯一的参数是代表有效URI的字符串:

  1. $results = $this->withURI('http://example.com/forums/categories')
  2. ->controller(\App\Controllers\ForumController::class)
  3. ->execute('showCategories');

良好的做法是始终在测试过程中提供URI以避免意外。

withBody($body)

允许您为请求提供自定义主体。在测试需要将JSON值设置为主体的API控制器时,这可能会有所帮助。唯一的参数是代表请求正文的字符串:

  1. $body = json_encode(['foo' => 'bar']);
  2. $results = $this->withBody($body)
  3. ->controller(\App\Controllers\ForumController::class)
  4. ->execute('showCategories');

检查响应

执行控制器时,将返回一个新的ControllerResponse实例,该实例提供了许多有用的方法以及对生成的请求和响应的直接访问。

isOK()

这提供了简单的检查,以将响应视为“成功”响应。这主要检查HTTP状态代码是否在200或300范围内:

  1. $results = $this->withBody($body)
  2. ->controller(\App\Controllers\ForumController::class)
  3. ->execute('showCategories');
  4. if ($results->isOK())
  5. {
  6. . . .
  7. }

isRedirect()

检查最终响应是否为某种重定向:

  1. $results = $this->withBody($body)
  2. ->controller(\App\Controllers\ForumController::class)
  3. ->execute('showCategories');
  4. if ($results->isRedirect())
  5. {
  6. . . .
  7. }

request()

您可以访问使用此方法生成的Request对象:

  1. $results = $this->withBody($body)
  2. ->controller(\App\Controllers\ForumController::class)
  3. ->execute('showCategories');
  4. $request = $results->request();

response()

这使您可以访问所生成的响应对象(如果有):

  1. $results = $this->withBody($body)
  2. ->controller(\App\Controllers\ForumController::class)
  3. ->execute('showCategories');
  4. $response = $results->response();

getBody()

您可以使用getBody()方法访问将发送给客户端的响应的主体。这可能是生成的HTML或JSON响应等:

  1. $results = $this->withBody($body)
  2. ->controller(\App\Controllers\ForumController::class)
  3. ->execute('showCategories');
  4. $body = $results->getBody();

响应助手方法

您返回的响应包含许多帮助程序方法,用于检查响应中的HTML输出。这些对于在测试中的断言中使用非常有用。

see()方法检查页面上的文本,看它是否通过其自身标记内是否存在,或者更具体地,如由类型,类,或id指定:

  1. // Check that "Hello World" is on the page
  2. $results->see('Hello World');
  3. // Check that "Hello World" is within an h1 tag
  4. $results->see('Hello World', 'h1');
  5. // Check that "Hello World" is within an element with the "notice" class
  6. $results->see('Hello World', '.notice');
  7. // Check that "Hello World" is within an element with id of "title"
  8. $results->see('Hellow World', '#title');

所述 dontSee() 方法是完全相反的:

  1. // Checks that "Hello World" does NOT exist on the page
  2. $results->dontSee('Hello World');
  3. // Checks that "Hellow World" does NOT exist within any h1 tag
  4. $results->dontSee('Hello World', 'h1');

seeElement()dontSeeElement() 非常类似于以前的方法,但不看的元素的值。相反,他们只是检查页面上是否存在元素:

  1. // Check that an element with class 'notice' exists
  2. $results->seeElement('.notice');
  3. // Check that an element with id 'title' exists
  4. $results->seeElement('#title')
  5. // Verify that an element with id 'title' does NOT exist
  6. $results->dontSeeElement('#title');

您可以使用seeLink()确保链接显示在页面上,并带有指定的文本:

  1. // Check that a link exists with 'Upgrade Account' as the text::
  2. $results->seeLink('Upgrade Account');
  3. // Check that a link exists with 'Upgrade Account' as the text, AND a class of 'upsell'
  4. $results->seeLink('Upgrade Account', '.upsell');

所述seeInField() 对于任何输入标签方法检查具有名称和值存在:

  1. // Check that an input exists named 'user' with the value 'John Snow'
  2. $results->seeInField('user', 'John Snow');
  3. // Check a multi-dimensional input
  4. $results->seeInField('user[name]', 'John Snow');

最后,您可以检查复选框是否存在,并使用seeCheckboxIsChecked() 方法进行检查:

  1. // Check if checkbox is checked with class of 'foo'
  2. $results->seeCheckboxIsChecked('.foo');
  3. // Check if checkbox with id of 'bar' is checked
  4. $results->seeCheckboxIsChecked('#bar');
以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号