Mockey/Laravel 静态调用 Authorizer::getResourceOwnerId

Mockey/Laravel with static call of Authorizer::getResourceOwnerId

我正在尝试使用 Mockery 来全面测试 Laravel 5.1 代码库的某些功能。

我没有在 Mockery 中进行大量的单元测试,当然也没有进行大量的静态调用...其中 Laravel 使用了大量。

我知道测试静态调用很糟糕..但是可以做到。在我认为好的做法(请随时纠正我)中,我试图模拟这些 类 以增加测试组件的分离。

我正在使用 \Mockery::mock('alias:{classname}') 功能来捕获这些静态调用。

例如,要检查当前登录的用户,使用以下方法找到 id:

$user_id = (int)Authorizer::getResourceOwnerId();

但是,测试功能似乎有一些局限性,我可能会使用错误 - 确切的问题如下:

测试结构

我目前的情况如下:

class AuthRoutesTest extends TestCase {

// ...

protected $mock_authorizer;

// ...

public function setUp()
{
    parent::setUp();

    // ...

    $this->mock_authorizer
        ->shouldReceive('getResourceOwnerId')
        ->andReturnValues(
            [null, 3, 3, 3]
        );
}

public function tearDown()
{
    \Mockery::close();
}

现在是测试 - 所有这些都需要 $user_id = (int)Authorizer::getResourceOwnerId(); 到 return 值。

public function testFirst() {
    // $user_id is null, then 3, 3 finally 3
}

问题是:

我想要.. 假设 testSecond() 有一组单独的值:比如 [1,2,null,4]

每次测试似乎都会重置数组(回到开头)。

注:-

这可能吗?如果可以,这是怎么做到的?

(我知道还有其他编码网站的方法..这更多是关于测试现有代码并避免重写 - 至少现在是这样)

如果您将 byDefault() 添加到您的期望中,则可以在 setUp() 方法中启动期望后覆盖该期望。

你会这样做:

public function setUp()
{
    parent::setUp();

    // ...

    $this->mock_authorizer
        ->shouldReceive('getResourceOwnerId')
        ->andReturnValues(
            [null, 3, 3, 3]
        )->byDefault();
}

然后在您的第二个测试用例中,可以覆盖您在 setUp 方法中定义的期望值,如下所示:

public function testSecond() {
    $this->mock_authorizer
        ->shouldReceive('getResourceOwnerId')
        ->andReturnValues(
            [1,2,null,4]
        );
}

这个 post: Override Mockery return values 也可能有用。

您还可以阅读 Mockery docs 中的期望和 byDefault() 方法。

此外,我建议您为 Authorizer 创建外观或使用依赖注入 class 而不是创建实例模拟(使用 Mockery 别名),因为实例模拟可能会影响其他 [=30] 中的测试=]es,从而导致不必要的问题。