CodeIgniter4 控制器测试

2020-08-17 17:43 更新

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

注解

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

助手特质

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

<?php namespace CodeIgniter;


use CodeIgniter\Test\ControllerTester;


class TestControllerA extends \CIDatabaseTestCase
{
    use ControllerTester;
}

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

<?php namespace CodeIgniter;


use CodeIgniter\Test\ControllerTester;


class TestControllerA extends \CIDatabaseTestCase
{
    use ControllerTester;


    public function testShowCategories()
    {
        $result = $this->withURI('http://example.com/categories')
                       ->controller(\App\Controllers\ForumController::class)
                       ->execute('showCategories');


        $this->assertTrue($result->isOK());
    }
}

辅助方法

controller($class)

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

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

execute($method)

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

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

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

withConfig($config)

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

$config = new Config\App();
$config->appTimezone = 'America/Chicago';


$results = $this->withConfig($config)
                ->controller(\App\Controllers\ForumController::class)
                ->execute('showCategories');

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

withRequest($request)

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

$request = new CodeIgniter\HTTP\IncomingRequest(new Config\App(), new URI('http://example.com'));
$request->setLocale($locale);


$results = $this->withRequest($request)
                ->controller(\App\Controllers\ForumController::class)
                ->execute('showCategories');

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

withResponse($response)

允许您提供一个Response实例:

$response = new CodeIgniter\HTTP\Response(new Config\App());


$results = $this->withResponse($response)
                ->controller(\App\Controllers\ForumController::class)
                ->execute('showCategories');

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

withLogger($logger)

允许您提供一个Logger实例:

$logger = new CodeIgniter\Log\Handlers\FileHandler();


$results = $this->withResponse($response)
                ->withLogger($logger)
                ->controller(\App\Controllers\ForumController::class)
                ->execute('showCategories');

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

withURI($uri)

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

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

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

withBody($body)

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

$body = json_encode(['foo' => 'bar']);


$results = $this->withBody($body)
                ->controller(\App\Controllers\ForumController::class)
                ->execute('showCategories');

检查响应

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

isOK()

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

$results = $this->withBody($body)
                ->controller(\App\Controllers\ForumController::class)
                ->execute('showCategories');


if ($results->isOK())
{
    . . .
}

isRedirect()

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

$results = $this->withBody($body)
                ->controller(\App\Controllers\ForumController::class)
                ->execute('showCategories');


if ($results->isRedirect())
{
    . . .
}

request()

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

$results = $this->withBody($body)
                ->controller(\App\Controllers\ForumController::class)
                ->execute('showCategories');


$request = $results->request();

response()

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

$results = $this->withBody($body)
                ->controller(\App\Controllers\ForumController::class)
                ->execute('showCategories');


$response = $results->response();

getBody()

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

$results = $this->withBody($body)
                ->controller(\App\Controllers\ForumController::class)
                ->execute('showCategories');


$body = $results->getBody();

响应助手方法

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

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

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

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

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

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

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

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

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

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

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

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

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

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号