CodeIgniter4 控制器測試

2020-08-17 17:43 更新

有了兩個(gè)新的幫助程序類和特征,可以方便地測試控制器。在測試控制器時(shí),您可以在控制器內(nèi)執(zhí)行代碼,而無需先執(zhí)行整個(gè)應(yīng)用程序引導(dǎo)過程。通常,使用功能測試工具會(huì)更簡單,但是可以在需要時(shí)使用此功能。

注解

由于尚未引導(dǎo)整個(gè)框架,因此有時(shí)您無法以這種方式測試控制器。

助手特質(zhì)

您可以使用任何一個(gè)基礎(chǔ)測試類,但是您確實(shí)需要ControllerTester在測試中使用特征:

<?php namespace CodeIgniter;


use CodeIgniter\Test\ControllerTester;


class TestControllerA extends \CIDatabaseTestCase
{
    use ControllerTester;
}

一旦包含了特征,就可以開始設(shè)置環(huán)境,包括請求和響應(yīng)類,請求主體,URI等。您指定要與該controller()方法一起使用的控制器,并傳入控制器的標(biāo)準(zhǔn)類名。最后,execute()使用要作為參數(shù)運(yùn)行的方法名稱來調(diào)用該方法:

<?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)

指定要測試的控制器的類名。第一個(gè)參數(shù)必須是完全限定的類名稱(即,包括名稱空間):

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

execute($method)

在控制器內(nèi)執(zhí)行指定的方法。唯一的參數(shù)是要運(yùn)行的方法的名稱:

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

這將返回一個(gè)新的幫助器類,該類提供了許多例程來檢查響應(yīng)本身。有關(guān)詳情,請參見下文。

withConfig($config)

允許您傳入ConfigApp.php的修改版本以測試不同的設(shè)置:

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


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

如果您不提供,則將使用應(yīng)用程序的App配置文件。

withRequest($request)

允許您提供適合您的測試需求的IncomingRequest實(shí)例:

$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');

如果不提供,則具有默認(rèn)應(yīng)用程序值的新IncomingRequest實(shí)例將傳遞到控制器中。

withResponse($response)

允許您提供一個(gè)Response實(shí)例:

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


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

如果不提供,則具有默認(rèn)應(yīng)用程序值的新Response實(shí)例將傳遞到控制器中。

withLogger($logger)

允許您提供一個(gè)Logger實(shí)例:

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


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

如果不提供,則具有默認(rèn)配置值的新Logger實(shí)例將傳遞到控制器中。

withURI($uri)

允許您提供一個(gè)新的URI,該URI模擬運(yùn)行該控制器時(shí)客戶端正在訪問的URL。如果您需要檢查控制器中的URI段,這將很有幫助。唯一的參數(shù)是代表有效URI的字符串:

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

良好的做法是始終在測試過程中提供URI以避免意外。

withBody($body)

允許您為請求提供自定義主體。在測試需要將JSON值設(shè)置為主體的API控制器時(shí),這可能會(huì)有所幫助。唯一的參數(shù)是代表請求正文的字符串:

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


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

檢查響應(yīng)

執(zhí)行控制器時(shí),將返回一個(gè)新的ControllerResponse實(shí)例,該實(shí)例提供了許多有用的方法以及對生成的請求和響應(yīng)的直接訪問。

isOK()

這提供了簡單的檢查,以將響應(yīng)視為“成功”響應(yīng)。這主要檢查HTTP狀態(tài)代碼是否在200或300范圍內(nèi):

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


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

isRedirect()

檢查最終響應(yīng)是否為某種重定向:

$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()

這使您可以訪問所生成的響應(yīng)對象(如果有):

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


$response = $results->response();

getBody()

您可以使用getBody()方法訪問將發(fā)送給客戶端的響應(yīng)的主體。這可能是生成的HTML或JSON響應(yīng)等:

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


$body = $results->getBody();

響應(yīng)助手方法

您返回的響應(yīng)包含許多幫助程序方法,用于檢查響應(yīng)中的HTML輸出。這些對于在測試中的斷言中使用非常有用。

see()方法檢查頁面上的文本,看它是否通過其自身標(biāo)記內(nèi)是否存在,或者更具體地,如由類型,類,或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() 對于任何輸入標(biāo)簽方法檢查具有名稱和值存在:

// 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');

最后,您可以檢查復(fù)選框是否存在,并使用seeCheckboxIsChecked() 方法進(jìn)行檢查:

// Check if checkbox is checked with class of 'foo'
$results->seeCheckboxIsChecked('.foo');
// Check if checkbox with id of 'bar' is checked
$results->seeCheckboxIsChecked('#bar');
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號