dopuzf0898 2016-05-11 10:43
浏览 68
已采纳

Mockey / Laravel与Authorizer :: getResourceOwnerId的静态调用

I am attempting to use Mockery to fully test some features of a Laravel 5.1 codebase.

I've not done a huge amount of unit testing in Mockery, and certainly not a huge amount with static calls... of which Laravel uses plenty.

I am aware that testing static calls is horrible.. but it can be done. In what I consider good practice (please feel free to correct me), I am attempting to mock these classes to increase separation of tested components.

I am using the \Mockery::mock('alias:{classname}') feature in order to catch these static calls.

For example, to check the current logged in user, the id is found using:

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

However, the testing features seem to have some limitations, and I could be using them wrong - the exact question follows below:

Testing structure

My current situation is as follows:

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();
}

Now the tests - all of these require $user_id = (int)Authorizer::getResourceOwnerId(); to return values.

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

And here's the problem:

I want to have.. lets say testSecond() with a separate set of values: say [1,2,null,4].

Each test seems to reset the array (go back to the beginning).

Note: -

  • I have tried to call ->shouldReceive('getResourceOwnerId') again - this does not help
  • I have tried to append the next values to the array, but it starts again at key 0

Is this possible, and if so, how is this done?

(I am aware there are other ways of coding a site.. this is more about testing existing code and avoiding the re-write - at least for now)

  • 写回答

1条回答 默认 最新

  • donglian8407 2016-05-17 09:58
    关注

    If you add byDefault() to your expectation it's possible to override the expectation after it's initiated in the setUp() method.

    You would do something like this:

    public function setUp()
    {
        parent::setUp();
    
        // ...
    
        $this->mock_authorizer
            ->shouldReceive('getResourceOwnerId')
            ->andReturnValues(
                [null, 3, 3, 3]
            )->byDefault();
    }
    

    Then in your second test case it's then possible to override the expectation you defined in the setUp method like this:

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

    This post: Override Mockery return values might also be useful.

    You can also read about expectations and the byDefault() method in the Mockery docs.

    Also, I would suggest that you create a facade or use dependency injection for the Authorizer class instead of creating an instance mock, (using Mockery alias) since instance mocks might affect tests in other classes and thereby result in unwanted issues.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 用hfss做微带贴片阵列天线的时候分析设置有问题
  • ¥50 我撰写的python爬虫爬不了 要爬的网址有反爬机制
  • ¥15 Centos / PETSc / PETGEM
  • ¥15 centos7.9 IPv6端口telnet和端口监控问题
  • ¥120 计算机网络的新校区组网设计
  • ¥20 完全没有学习过GAN,看了CSDN的一篇文章,里面有代码但是完全不知道如何操作
  • ¥15 使用ue5插件narrative时如何切换关卡也保存叙事任务记录
  • ¥20 海浪数据 南海地区海况数据,波浪数据
  • ¥20 软件测试决策法疑问求解答
  • ¥15 win11 23H2删除推荐的项目,支持注册表等