【问题标题】:Laravel 5.3 PHPUnit Test Service Provider Persisted Between RequestsLaravel 5.3 PHPUnit 测试服务提供者在请求之间持续存在
【发布时间】:2017-07-06 08:35:43
【问题描述】:

我正在使用 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();

【问题讨论】:

  • 好吧,只是一点评论而不是答案,我通常怀疑each()函数的行为。
  • 我通过放弃使用 each 并只是粘贴内部语句几次来模拟循环和每个粘贴集 $province = $provinces->shift(); 来测试这一点,所以没有其他任何改变。在运行第二组粘贴语句时,它仍然认为第一个用户已登录。

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


【解决方案1】:

所以这似乎是由于“框架的微妙之处”,根据这个 Github issue,应用程序实例被重用于所有请求。

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

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

【讨论】:

    猜你喜欢
    • 2021-11-01
    • 1970-01-01
    • 2016-10-06
    • 2021-09-29
    • 2013-09-19
    • 1970-01-01
    • 2015-02-27
    • 2020-08-24
    • 2020-01-31
    相关资源
    最近更新 更多