通过php单元测试中的“ DataProvider”方法中的“ setUpBeforeClass”访问静态变量

时间:2018-10-18 05:33:55

标签: php phpunit php-7 php-7.1 phpunit-testing

我正在写我的phpunit test。我需要初始化dataprovider方法来对我的测试之一进行分组。但是我无法获得在setUpBeforeClass方法中声明的静态变量。这些变量正在向我返回null

Google何时进行搜索,文档称dataprovider方法将在setUpBeforeClass之前执行。

有什么方法可以覆盖它并从dataprovider进行静态变量访问?

示例代码

在课程功能之前进行设置

public static function setUpBeforeClass()
{
    self::sampleVariable = 'Sample Data';
}

数据提供者功能

public function sampleDataProvider()
{
    echo self::sampleVariable;
}

3 个答案:

答案 0 :(得分:1)

数据提供者与测试用例设置流程分离的原因是,可以将它们定义为外部类方法。它还涉及将数据注入测试。考虑这样的代码:

class SampleTest extends PHPUnit_Framework_TestCase
{
    public function __construct($name = null, array $data = array(), $dataName = '') {
        parent::__construct($name, $data, $dataName);
        var_dump('constructed');
    }
    public static function setUpBeforeClass() {
        parent::setUpBeforeClass();
        var_dump('beforeClass');
    }

    public function setUp(){
        var_dump('before');
    }

    /**
     * @dataProvider sampleDataProvider
     */
    public function testMethod($expected, $actual) {
        var_dump('test');
        $this->assertEquals($expected, $actual);
    }

    public function sampleDataProvider() {
        var_dump('dataProvider');
        return [
            [1, 1],
            [2, 2],
        ];
    }
}

运行它时,您会注意到首先构造了SampleTest实例,然后调用了dataProvider,然后创建了两个SampleTest实例(一个测试方法乘以来自dataprovider的两个数据集),然后运行beforeClass方法,然后运行两次测试方法,注入来自提供程序的数据集。

尚不清楚您的特定用例是什么,但是可能可以将上述用例重构为如下形式:

class AnotherSampleTest extends PHPUnit_Framework_TestCase
{
    public function testMethod() {
        foreach ($this->sampleDataProvider() as $dataSet) {
            list($expected, $actual) = $dataSet;
            $this->assertEquals($expected, $actual);
        }
    }

    public function sampleDataProvider() {
        return [
            [1, 1],
            [2, 2],
        ];
    }
}

这里sampleDataProvider只是一个常规方法,因此您负责如何以及何时调用它,无论如何,它会在setUpBeforeClasssetUp之后被调用,因此它可以访问任何内容在此处进行设置或修改,以便您可以进行任何调整。

这种方法的缺点是您实际上失去了将一种测试方法分成多种方法的麻烦。因此,与每个测试只有几个断言的多个测试相比,这将是一个具有多个断言的测试。另外,您可能需要特别注意设置(我的意思是您可能需要在每次迭代之前刷新smth)-可通过手动调用setUp(乍一看)来解决。

如果没有关于您特定用例的详细信息,不要认为不可能提出任何进一步的建议。

答案 1 :(得分:0)

尝试将变量sampleVariable声明为     静态,然后检查。

class MyClass
{  
private static $sampleVariable;
}

答案 2 :(得分:0)

PHPUnit处理数据提供程序方法的方式很奇怪。它们不是从运行测试的同一对象中调用的,因此在进行DP调用的对象中,setupBeforeClass将不会运行。这真是愚蠢的IMO,但是我敢肯定,这样做是有原因的(xmike实际上解释了in his answer。毕竟不是那么愚蠢;-)。

鉴于您的分配只是一个静态值(无论如何,在您的示例中),您能否简单地将其声明为类属性而不是通过setUpBeforeClass进行设置?我想情况可能会更复杂,因为您的示例演示了阻止这种方法的情况:我只有您的示例可以作为我的建议的基础。

另一件事是将setUpBeforeClass中的逻辑抽象为一个单独的方法,并同时从sampleDataProvidersetUpBeforeClass中调用该方法。