我最近成功地使用Mockery和PHPUnit测试。然而,我正在使用的项目中存在一个依赖项,它使用静态方法调用来与API进行交互。我正在努力测试一个特定的用例,感觉我会在开发路线图中找到其他类似的东西。
以此类为例:
namespace Name\Space;
class User
{
/**
* @return \Name\Space\User[]
*/
public static function list(): array
{
// ...
}
public static function create(array $attrs): User
{
// ...
}
}
如果我只是想断言一个方法返回一个基本类型,如一个数组:
Mockery::mock('alias:\Name\Space\User')
->shouldReceive('list')
->andReturn([]);
它工作正常,主要是因为我没有测试数组内容。
但是,我必须调用create
方法,该方法返回类本身的实例(User
)。如果我做这样的事情:
$user = new \Name\Space\User();
Mockery::mock('alias:\Name\Space\User')
->shouldReceive('create')
->andReturn($user);
显然,别名不起作用,因为类已经通过自动加载器加载(在这种情况下是作曲家)。
有没有人建议如何解决这个问题?
如何在闭包中创建User?
<?php
$user = Mockery::mock('overload:\Name\Space\User')
->shouldReceive('create')
->andReturnUsing(function() {
return new \Name\Space\User();
});
嘲弄静态的东西总是很痛苦。我建议创建一个调用静态API调用的Proxy对象,只返回API结果,并在需要调用API的任何地方注入该对象。
这样,通过简单地模拟代理对象就可以轻松进行测试。
然后可以在纯单元测试范围之外的端到端测试中测试代理对象本身。
你仍然可以做更多这样的侵入性的东西,如https://www.pagemachine.de/blog/mocking-static-method-calls/?cn-reloaded=1
但编写不属于您的单元的代码纯粹是为了让一些可测试的东西对我来说感觉不对。