为什么Codeception在Laravel中不应该运行的路由上运行中间件?

时间:2015-11-04 04:52:05

标签: php laravel laravel-5 codeception laravel-middleware

所以我是一个代码新手,我试图弄清楚如何使用相同的方式测试我的Web服务。我已经为authenticate路由编写了我的第一个简单测试,以确保应用程序正在吐出JWT令牌。测试看起来像这样:

<?php 
$I = new ApiTester($scenario);
$I->wantTo('authenticate a user');
$I->haveHttpHeader('Content-Type', 'application/x-www-form-urlencoded');
$I->sendPOST('/api/authenticate', [
    'username' => 'archive',
    'email' => 'admin@admin.com',
    'password' => 'password'
]);
$I->seeResponseCodeIs(200);
$I->seeResponseIsJson();

在我的辩护中,我尝试过Postman的同一个POST,但效果很好。

api.suite.yml

class_name: ApiTester
modules:
    enabled:
        - REST:
            url: http://localhost:8000/api/
            depends: Laravel5
    config: 
        Laravel5:
            environment_file: .env.testing

我在此测试中遇到的问题是它没有看到200 OK作为响应代码,而是看到500。后来我意识到我可以在_output目录中查看相同的输出,我看到了这个错误:

  

无法从请求中解析令牌

令我惊讶的是,authenticate路由甚至不需要令牌,因此我继续查看我的应用程序中正在解析的令牌。最后我意识到有一个名为ChangeDb的中间件位于Kernal中,它看起来要检查除authenticate路由之外的每个请求的令牌。它看起来像这样:

public function handle($request, Closure $next)
{
    if($request->path() != 'api/authenticate'){
        $username = \JWTAuth::parseToken()->getPayload()->get('username');

        if(! $username){
            \Config::set('database.connections.tenant.database', 'archive');
            \DB::reconnect();
            \DB::setDatabaseName('archive');
        }else{
            \Config::set('database.connections.tenant.database', $username); 
        }
    }

    return $next($request);
}

但是当我试图从Kernal中评论这个时,测试运行良好,并给我绿色。所以当我从Postman和其他ajax请求尝试时,这个中间件运行正常,但是当Codeception尝试请求时,if statement显然返回true,因为它查看了令牌,这是我的测试失败的地方

那为什么会这样呢?从Codece生成的请求是否与Postman或我前端的ajax应用程序生成的请求有所不同?如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

因为我假设Laravel5因为REST部分中的依赖关系是问题所在。它没有模拟真实的HTTP请求,这就是middleware无法分辨请求来自何处的原因。我将其更改为PhpBrowser,现在可以使用了。 PhpBrowser显然模拟了真实的HTTP请求。