PHPUnit使用dataProvider为每个单独的测试运行setUp方法

3
我有一个PHPUnit测试testFoo(),并使用数据提供程序fooProvider()。在testFoo()的开头,我使用Runkit重新定义了一个方法,以便在该方法返回我重新定义为返回的内容时测试预期结果。但是,重新定义方法需要一些时间,因此我希望它仅在此测试中发生一次。
PHPUnit框架是否提供功能来指定我想要在testFoo()运行之前只运行一次的代码,并且不是每个由fooProvider()返回的元素或测试套件中的每个测试都运行一次(例如setUp())?

@beforeClass怎么样? - xmike
@xmike 我需要多次重新定义该方法以返回不同的内容用于不同的测试,因此它确实需要针对每个单独的测试进行特定定义。 - thanksd
如果我是你,我会继续使用@before,但在测试中实现自己的提供程序,例如 $dataSets = $this->getDataSets()(应返回数据数组),然后通过循环来进行断言。这样,PHPUnit框架只会启动一次测试,因此setUp()也只会运行一次(从它的角度来看,测试只会运行一次)。 - xmike
我猜我希望有一个@beforeTest注释来指定在测试之前运行的函数,这样我就不需要在我的测试方法中添加循环和引用设置。但是从我所看到的PHPUnit文档中,似乎并没有这个功能? - thanksd
其实你是对的,@before 在每个测试之前只运行一次。问题在于,如果你使用了 @dataProvider,测试将会为每个数据集重新启动,因此也会执行 @before -- 这就是 PHPUnit 框架处理数据提供的方式(这是因为测试必须在每个新数据集上被调用,并将该新集作为参数接收)。因此,避免重新启动的方法就是不使用自动化的数据提供。 - xmike
1个回答

3
使用静态私有属性标记该方法已被重新定义。需要使用静态属性,因为dataProvider为每个测试用例实例化测试类。
class FooTest extends PHPUnit_Framework_TestCase
{
    private static $redefined = false;

    /**
     * @dataProvider fooProvider
     */
    public function testFoo()
    {
        if (! self::$redefined) {

            // redefinition code goes here

            self::$redefined = true;
        }
    }
}

我希望能从PHPUnit框架内找到解决方案(我将编辑我的问题以澄清这一点)。我在不同的测试中重新定义相同的方法,如果不必手动跟踪每个方法是否已被重新定义,并且为每个测试重新定义到适当的替代方法,那将是很好的。 - thanksd
在这种情况下,您可以拥有一个处理方法重新定义并从所有测试中使用的类。该类应该知道哪些方法已经被重新定义,并且如果方法已经被重新定义,则不执行任何操作。 - gontrollez
这样做是可行的,但与问题评论中xmike的解决方法或类似于PHPUnit Framework内部的setup()函数相比,这是一种相当迂回的防止方法被多次重新定义的方式。 - thanksd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接