当我编码时,我经常看到这样的东西:
testMyMethod() {
....
$mockMyServiceB
->expects($this->once())
->method('myMethodA')
->with(myvalue1, myvalue2, myvalue3)
->willReturn($someMockResult);
$myServiceA = new ServiceA($mockMyServiceB)
$results = $myServiceA->something();
$this->assertEquals(['resultA', 'resultB'], results);
}
不确定,但我认为,当您编写越来越多的测试时,这会使它们快速且容易地失去可读性。你只是放了太多的信息(预计与收益混合)。你需要了解每个测试的参数顺序,期望,执行顺序和返回值....我认为太多了。
我正在考虑将代码移动到您只测试myMethodA的正确使用的位置,然后再进行另一个测试,您可以只关注结果,如下所示:
testMyMethodUseServiceBCorrectly() {
....
// this time no WillReturn, just focus on how is used
$mockMyServiceB
->expects($this->once())
->method('myMethodA')
->with(myvalue1, myvalue2, myvalue3);
$myServiceA = new ServiceA($mockMyServiceB)
$myServiceA->something();
}
testMyMethodUseServiceResults() {
....
// this time no Expects() or With(), just focus on results
$mockMyServiceB
->method('myMethodA')
->willReturn(myvalue1, myvalue2, myvalue3);
$myServiceA = new ServiceA($mockMyServiceB)
$this->assertEquals(['resultA', 'resultB'], $myServiceA->something());
}
我认为这清楚地表明了您正在测试的内容,并且还会生成较小的测试。但不确定是否也常见......是推荐做法吗?
答案 0 :(得分:0)
您仍然可以使用受保护或私有方法来配置模拟。例如,我们有一个项目,class BaseTestCase extends TestCase
有一个基本的createMock($classname)
方法,从中扩展所有单元测试,以便为大多数模拟建筑用途提供一些代码。
请记住编写可读的测试代码,其中包含变量和方法的明确名称,并尽可能重用代码。
另外,请记住,如果您的测试变得越来越大,也许您需要重构您的课程并获得一些简化的服务。
答案 1 :(得分:-1)
这里有一些事情需要改进:
将已测试服务的创建实例移至setUp()方法
使用数据提供程序将测试与数据https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.data-providers
然后测试看起来像传统的PHPunit测试。当您在数据提供者(Example 2.6: Using a data provider with named datasets)内正确命名测试用例时,数据提供者也会增加很多可读性和透明度。