Laravel 5.3 PHPUnit测试服务提供程序在请求之间保持

时间:2017-02-17 00:42:31

标签: laravel laravel-5 phpunit laravel-5.3 jwt

我正在使用JWTAuth令牌进行身份验证。在测试中,我在验证后收到令牌时,我已经在每个请求上传递令牌,但是当需要在循环中对一组不同用户运行一些特定测试时,对单个用户起作用的测试开始失败,没有意义。

通过日志记录,我可以看到,无论我是否正在调用注销,我在每个请求上使用的服务提供程序只能在第一个请求上构建,然后看起来仍然存在。因此,即使用户已注销并且新用户已登录并具有新令牌,服务提供程序也不会像生产应用程序中那样在每个请求上重新实例化。

有没有办法让服务提供商不会持久存储或存储在请求之间?我注意到通过调试我甚至不需要在后续经过身份验证的路由上登录服务器后传递令牌,因为它只是重用服务提供者中的持久数据。

下面的示例适用于任何单个用户,但是当对多个用户进行迭代时,单个用户不能拥有两个打开的应用程序的规则会抛出并指示第一个用户仍在第二次迭代中使用。

public function applicant_can_prequalify_if_age_of_majority_for_province_or_older()
{
    // Arrange
    $this->runPrequalifySeeders();

    $provinces = Province::select('id', 'name', 'majority_age')->get();
    $provinces->each(function ($province) {

        // Act
        $provinceName = str_replace(' ', '', strtolower($province->name));
        $username = "{$provinceName}@example.com";

        $applicant = $this->createApplicant($username);
        $this->login($applicant->username);

        Log::info($applicant->username); // correct username: check
        Log::info($this->token); // different token each time: check

        // Applicants can only have one application at a time hence the
        // new user for each iteration per province: fails on second
        // iteration as service container persisted... I think
        $application = $this->createNewApplication()->decodeResponseJson();

        // Removed for brevity...

        $this->logout();
    });
}

更新

如果它与each的使用有关,我会粘贴语句几次并将省份移出集合,它仍然在Act 2中认为Act 1的用户}已通过身份验证。

// Act 1
$province = $provinces->shift();
$provinceName = str_replace(' ', '', strtolower($province->name));
$username = "{$provinceName}@example.com";

$this->createApplicant($username)->login($username);
$application = $this->createNewApplication()->decodeJson();

// Removed for brevity

$this->logout();

// Act 2
$province = $provinces->shift();
$provinceName = str_replace(' ', '', strtolower($province->name));
$username = "{$provinceName}@example.com";

$this->createApplicant($username)->login($username);
$application = $this->createNewApplication()->decodeJson();

// Removed for brevity

$this->logout();

更新2

即使我已经在服务器上注销了被调用的方法,因为端点被点击,如登录,注销等。我想检查注销实际上是否正在工作并将令牌列入黑名单,它基于此在第二次创建新的应用程序端点被命中后抛出Unauthenticated 401错误的测试。所以看起来确实没有清除服务提供商。

// Act
$province = $provinces->shift();
$provinceName = str_replace(' ', '', strtolower($province->name));
$username = "{$provinceName}@example.com";

$this->createApplicant($username)->login($username);
$application = $this->createNewApplication()->decodeJson();

$this->logout();

// 401 server response since token was successfully blacklisted
$application = $this->createNewApplication()->decodeJson();

1 个答案:

答案 0 :(得分:1)

所以这似乎是由于框架的微妙之处"根据此Github issue将应用程序实例重用于所有请求的位置。

显然你应该能够通过调用$this->refreshApplication()清除IoC,但是当我这样做时它会丢弃数据库,因为我使用的是内存数据库。

因此,我只是在执行断言后删除每次迭代的应用程序,这解决了这个特定的问题。