我正试图使用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();
返回值。
public function testFirst() {
// $user_id is null, then 3, 3 finally 3
}
问题是:
我想要。。比方说testSecond()
具有一组单独的值:比如[1,2,null,4]
。
每个测试似乎都会重置数组(回到开头)。
注:-
- 我尝试再次致电
->shouldReceive('getResourceOwnerId')
,但没有帮助 - 我试图将下一个值附加到数组中,但它在键0处再次开始
这可能吗?如果可能,如何做到这一点?
(我知道还有其他方法可以对网站进行编码。这更多的是为了测试现有代码并避免重写——至少目前是这样)
如果将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]
);
}
这篇文章:覆盖Mockery返回值可能也很有用。
您还可以在Mockery文档中阅读有关期望值和byDefault()
方法的内容。
此外,我建议您为Authorizer类创建一个facade或使用依赖项注入,而不是创建实例mock(使用Mockery别名),因为实例mock可能会影响其他类中的测试,从而导致不必要的问题。