来自数据库的PHPUnit dataProvider

时间:2016-03-21 13:57:34

标签: php symfony phpunit

我有简单的PostControllerTest类:

<?php

namespace AppBundle\Tests\Controller;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Bundle\FrameworkBundle\Client;

class PostControllerTest extends WebTestCase
{
    /**
     * @var Client
     */
    private $client;

    public function setUp() {
        $this->client = static::createClient();

    }

    public function idProvider()
    {
        return [
            ["1"],
            ["2"],
            ["3"],
        ];
    }

    /**
     * @dataProvider idProvider
     */
    public function testGet($id)
    {
        $this->client->request('GET', '/post/'.$id);
        $this->assertTrue($this->client->getResponse()->isSuccessful());
    }
}

testGet方法使用idProvider来发出/post/{id}之类的请求并断言成功回复,其中{id}id实体的真实Post数据库中。

一切都很好,但是如果Postid = 1一起删除会怎么样?

我需要从数据库中获取一些id,例如last或\和随机3个,并将其作为testGet传递给dataProvider(或不dataProvider }?)

我将Symfony 2.8.3与PHPUnit 5.2.11。

一起使用

如何解决?任何建议表示赞赏。谢谢!

2 个答案:

答案 0 :(得分:2)

在测试运行之前,您应该确保应用程序的“正确”状态。 因此,您可以使用setUp()方法创建具有给定ID的新帖子,然后运行测试,而不是指望帖子在那里。

对空白的测试专用数据库运行测试可能是个好主意。这将使您的测试非常可预测,因此您不必担心将setUp方法中的id传递给testCase。

否则,您可以使用静态方法创建一个帮助程序类,用于存储以后可以提取的“事物”。在您的情况下可能足够的另一个解决方案是创建一个单独的类属性来存储post id。

希望这有帮助。

答案 1 :(得分:1)

这个很棘手,因为据我所知,dataProviders不能调用上下文方法,只能调用静态方法,因为它们是在类实例化之前调用的。

解决方法是停止使用dataProviders并在断言中循环:

public function testGet($id)
{
    $howMany = 3;
    //This method should create posts using your Business Logic layer
    $posts = $this->createPosts($howMany);
    foreach($posts as $post){
        $this->client->request('GET', '/post/'.$post->getId());
        $this->assertTrue($this->client->getResponse()->isSuccessful());
    }
}

顺便说一句,只是说这些测试往往相当缓慢,所以我会问自己是否值得为它检查3次相同的东西,而不是尝试一个存在而另一个没有。