【问题标题】:Queue::fake not work with Laravel5 codeception moduleQueue::fake 不适用于 Laravel5 代码接收模块
【发布时间】:2020-03-25 06:53:31
【问题描述】:

我为 Laravel 应用程序编写代码接收和模块 Laravel5REST 的测试。

api测试之一:

public function testEmailRegistration(ApiTester $I) {

...

// Not correct data
$I->sendPOST($route, [
    'first_name' => (string)$this->faker->randomNumber(),
    'password' => $this->faker->password(1, 7),
    'email' => 'not_valid_email',
]);

$I->seeResponseCodeIs(HttpCode::UNPROCESSABLE_ENTITY);

// Correct data
\Illuminate\Support\Facades\Queue::fake();

$I->sendPOST($route, [
    'first_name' => $firstName,
    'password' => $password,
    'email' => $email,
]);

\Illuminate\Support\Facades\Queue::assertPushed(\App\Jobs\SendEmail::class);

...

}

我发送关于不正确和正确数据的请求并做出一些断言。此外,我检查了该作业是否存在于队列中。

执行测试后报错:

[Error] Call to undefined method Illuminate\Queue\SyncQueue::assertPushed()

Queue:fake之后的门面\Illuminate\Support\Facades\Queue必须解析为QueueFake,但实际上还是QueueManager,因此assertPushed函数是未定义的。

执行$I->sendPOST() 重置调用Queue::fake。它发生在 laravel 5 模块\Codeception\Lib\Connector\Laravel5,方法doRequest

protected function doRequest($request)
{
        if (!$this->firstRequest) {
            $this->initialize($request);
        }
        $this->firstRequest = false;

        $this->applyBindings();
        $this->applyContextualBindings();
        $this->applyInstances();
        $this->applyApplicationHandlers();

        $request = Request::createFromBase($request);
        $response = $this->kernel->handle($request);
        $this->app->make('Illuminate\Contracts\Http\Kernel')->terminate($request, $response);

        return $response;
}

每次调用doRequest,除了第一个init应用程序和Queue::fake的一些配置被清除。

其中一个决定是每次测试一个请求。在测试中提出多个请求时,Queue::fake 是否还有其他变体可以工作?

【问题讨论】:

标签: php laravel codeception


【解决方案1】:

我不确定 Laravel 模块为什么会这样做,但我找到了一个允许您使用假货的解决方法:

public function someTest(ApiTester $I): void
{
    // what the SomeFacade::fake method call does is basically create
    // a fake object and swaps it for the original implementation in 
    // the app container, so the we're recreating that behavior here
    // only this will be persisted even after the request is issued:
    $notification_fake = new NotificationFake();
    // `haveInstance` is a method from Laravel Codeception Module 
    // which sets an object in the app container for you:
    $I->haveInstance(ChannelManager::class, $notification_fake);

    // making the request
    $I->sendPUT('some url', $some_payload);

    // assertions
    $I->canSeeResponseCodeIs(Response::HTTP_OK);
    $notification_fake->assertSentToTimes($expected_user, MyNotification::class, 1);
}

请注意,此测试方法仅用于说明目的,它遗漏了一些细节,因此未定义变量等。

另外请注意,我使用了在Illuminate\Notifications\ChannelManager 注册的通知假货,与大多数假货不同,您可以使用他们的别名注册,例如queue。因此,您必须检查正在实例化的内容以及如何自行交换它。您可以在每个服务的相应服务提供商中找到它。 大多数情况下是外观的小写名称。

【讨论】:

    猜你喜欢
    • 2020-04-14
    • 2014-11-27
    • 2018-12-19
    • 2020-05-13
    • 2012-05-02
    • 1970-01-01
    • 2017-02-21
    • 2018-06-13
    • 1970-01-01
    相关资源
    最近更新 更多