我可以使用@dataProvider或@depends吗?

时间:2017-09-06 16:10:57

标签: php unit-testing mocking phpunit

我有一个类(称为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方法),我可以使用注释{{1} }或@dataProvider,像这样(例子):

@depends

有可能吗?

1 个答案:

答案 0 :(得分: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();
}

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

关于 @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,
        ],
    ];
}