这个练习在phpunit上有用吗?

时间:2017-08-24 11:32:12

标签: php testing phpunit

当我编码时,我经常看到这样的东西:

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

我认为这清楚地表明了您正在测试的内容,并且还会生成较小的测试。但不确定是否也常见......是推荐做法吗?

2 个答案:

答案 0 :(得分:0)

您仍然可以使用受保护或私有方法来配置模拟。例如,我们有一个项目,class BaseTestCase extends TestCase有一个基本的createMock($classname)方法,从中扩展所有单元测试,以便为大多数模拟建筑用途提供一些代码。

请记住编写可读的测试代码,其中包含变量和方法的明确名称,并尽可能重用代码。

另外,请记住,如果您的测试变得越来越大,也许您需要重构您的课程并获得一些简化的服务。

答案 1 :(得分:-1)

这里有一些事情需要改进:

  1. 将已测试服务的创建实例移至setUp()方法

  2. 使用数据提供程序将测试与数据https://phpunit.de/manual/current/en/writing-tests-for-phpunit.html#writing-tests-for-phpunit.data-providers

  3. 分开

    然后测试看起来像传统的PHPunit测试。当您在数据提供者(Example 2.6: Using a data provider with named datasets)内正确命名测试用例时,数据提供者也会增加很多可读性和透明度。