我们正在试验 Mockery (0.9.2)的奇怪行为,同时使用 Symfony 控制器,该控制器使用抓取的几个请求参数请求服务。我们使用 PHPUnit (3.7)作为测试框架。
我们接近TDD的方式是使用 setUp 方法创建模拟并使用 byDefault()进行配置,以便它们可以提供中立的快乐流场景。然后,在每种测试方法中,我们都会对我们对模拟行为的期望有所了解。
我在概念验证测试中分离了问题,只是为了使分析更容易。我们走了。
这是测试类本身:
class FooTest extends \PHPUnit_Framework_TestCase
{
private $request;
public function setUp()
{
$this->request = \Mockery::mock('Symfony\Component\HttpFoundation\Request');
$this->request->shouldReceive('get')->with('a')->andReturnNull()->byDefault();
$this->request->shouldReceive('get')->with('b')->andReturnNull()->byDefault();
}
public function test_bar_checks_request_a_parameter()
{
$this->request->shouldReceive('get')->with('a')->andReturn('a')->once();
$foo = new Foo($this->request);
$foo->bar();
}
}
这是经过测试的课程:
use Symfony\Component\HttpFoundation\Request;
class Foo
{
private $request;
function __construct(Request $request)
{
$this->request = $request;
}
public function bar()
{
$a = $this->request->get('a');
$b = $this->request->get('b');
}
}
在测试 test_bar_checks_request_a_parameter 中,我希望 bar()方法在调用 get('a')时获取'a'在调用 get('b')时获取 null 时请求模拟。
但是,相反,我们收到了这个错误:
No matching handler found for Mockery_0_Symfony_Component_HttpFoundation_Request::get("b").
似乎说 Request 模拟忘记了我们为 get('b')调用而设置的setUp
shouldReceive('get')->with('b')->andReturnNull()->byDefault()
这是一个Mockery限制吗?对我们来说是一种不好的方法,可能会有一种测试气味吗?
提前致谢
答案 0 :(得分:1)
这是一个Mockery限制。当您为方法设置新的期望时,Mockery会禁用该方法的所有byDefault()
期望值,即使它们是使用不同的参数设置的。
有一个未解决的问题:
https://github.com/padraic/mockery/issues/353
您可以通过使用值数组和每次计算返回值的函数来解决此问题。诀窍是使数组可以从测试方法中访问,因此您可以更改返回值:
class FooTest extends \PHPUnit_Framework_TestCase
{
private $request;
private $get_return_values = array();
public function setUp()
{
$this->request = \Mockery::mock('Symfony\Component\HttpFoundation\Request');
$this->request->shouldReceive('get')->andReturnUsing(function($arg) {
return isset($this->get_return_values[$arg]) ? $this->get_return_values[$arg] : null;
});
}
public function test_bar_checks_request_a_parameter()
{
$this->get_return_values['a'] = 'a';
$foo = new Foo($this->request);
$foo->bar();
}
}