PHPUnit数据提供者从数据库

3

我有一个简单的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} 是数据库中 Post 实体的真实 id
一切都很好,但是如果要删除 id = 1Post 怎么办?
我需要从数据库中获取一些 id,例如最后或/和随机的3个,并将其作为 dataProvider(或不是 dataProvider?)传递给 testGet
我使用 Symfony 2.8.3 和 PHPUnit 5.2.11。
如何解决?任何建议都将不胜感激。谢谢!

你如何加载测试数据? - Matteo
2个回答

2
在测试运行之前,您应该确保您的应用程序处于“正确”的状态。因此,您可以使用setUp()方法创建一个具有给定id的新帖子,然后运行测试,而不是依赖于已经存在的帖子。
最好在一个全新、专门为测试用途的数据库上运行测试,这将使您的测试变得非常可预测,因此您不必担心将id从setUp方法传递到testCase中。
否则,您可以创建一个带有静态方法的辅助类来存储“事物”,稍后可以提取它们。另一个可能在您的情况下足够的解决方案是创建一个单独的类属性来存储帖子id。
希望这能帮到您。

1
这个有点棘手,因为据我所知,数据提供程序不能调用具有上下文的方法,只能调用静态方法,因为它们在类实例化之前调用。一种解决方法是停止使用数据提供程序,在断言中执行循环:
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());
    }
}

作为一个旁注,只是想说这些测试往往非常缓慢,所以我会质疑自己是否值得为了这个而检查三次相同的东西,而不是尝试一个存在的和另一个不存在的东西。

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