【问题标题】:@dataProvider or @depends can I use it?@dataProvider 或 @depends 我可以使用它吗?
【发布时间】:2017-09-06 16:10:56
【问题描述】:

我有一个类(称为FormFilters),该类在一个方法中调用其方法,在本例中为getProject

class FormFilters extends KernelTestCase 
{
    public function getProject($filters)
    {
        $this->filters = $filters;
        $this->getWhere($this->filters);
    }

    public function getWhere()
    {
        if ($this->filters->isValid()) {
            $this->sql = $this->filterName($this->filters->get('name')->getData());
        }
    }

    public function filterName() 
    {
        //....
    }
}

这是getProject方法测试:

public function test_getProject()
{
    $formInterface = $this->createMock('Symfony\Component\Form\FormInterface');

    $formInterface
        ->expects($this->at(0))
        ->method('isValid')
        ->willReturn(true); // come into conditional

    $formInterface
        ->expects($this->at(1))
        ->method('get')
        ->with('name')
        ->will($this->returnSelf());

    $formInterface
        ->expects($this->at(2))
        ->method('getData')
        ->will('data example');  

    $formFilters = new FormFilters();
    $formFilters->getProject($formInterface); // my mock
}

到目前为止一切顺利。现在,我想测试getWhere方法,我可以独立完成,但是如果getProject有相同的测试(调用getWhere方法),我可以使用注释@dataProvider@depends,像这样(示例):

/**
 * @depends or/and @dataProvider test_getProject
 */
 public function test_getWhere($dataToDepends)
 {
     // ... test ready !
 }

有可能吗?

【问题讨论】:

    标签: php unit-testing mocking phpunit


    【解决方案1】:

    在您当前的设置中,getWhere() 的正面案例已经过测试(在 test_getProject() 的范围内)。因此,当解释器不进入 IF 时,getWhere() 中的还有待测试的内容是一个否定情况。

    测试可能是:

    public function test_getWhere_invalid_filters()
    {
        $formInterface->expects($this->once())
                        ->method('isValid')
                        ->willReturn(false);
        $formInterface->expects($this->never())
                        ->method('get');
        $formInterface->expects($this->never())
                        ->method('getData');
    
        $formFilters = new FormFilters();
        //todo: inject $formInterface into $formFilterssomehow at this line.
    
        $formFilters->getWhere();
    }
    

    关于 @depends 的问题 - 通常在第一次测试完成之前无法执行第二次测试时使用。例如,第一个案例在数据库中创建了一些实体,第二个测试尝试删除在之前的测试中创建的实体。另一个例子 - 类的静态属性,在一个测试中设置并期望在另一个测试中读取。一般来说,不鼓励有依赖测试以及依赖代码单元。无论如何,这不是你的情况,也不是你测试所需要的。

    关于 @dataProvider - 这是非常有用的注释。它允许将测试的逻辑与测试的数据分开。它还允许对不同的数据集重复使用相同的测试。上面发布的测试,使用@dataProvider 将如下所示:

    /**
     * @dataProvider getWhere_invalid_filters_data_provider
    */
    public function test_getWhere_invalid_filters($isValid, $getCallsCount, $getDataCallsCount)
    {
        $formInterface->expects($this->once())
                        ->method('isValid')
                        ->willReturn($isValid);
        $formInterface->expects($this->exactly($getCallsCount))
                        ->method('get');
        $formInterface->expects($this->exactly($getDataCallsCount))
                        ->method('getData');
    
        $formFilters = new FormFilters();
        //todo: inject $formInterface into $formFilterssomehow at this line.
    
        $formFilters->getWhere();
    }
    
    public function getWhere_invalid_filters_data_provider()
    {
        return [
            'case 1' => [
                 'isValid' => false,
                 'getCallsCount' => 0,
                 'getDataCallsCount' => 0,
            ],
        ];
    }
    

    【讨论】:

      猜你喜欢
      • 2012-05-29
      • 1970-01-01
      • 2021-03-22
      • 2010-11-13
      • 1970-01-01
      • 1970-01-01
      • 2015-09-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多