我创建了一个非常简单的REST控制器Symony2与控制器动作数据库插入/更新/删除。
有没有写这些控制器动作单元/集成测试,不污染生产数据库的好办法? 我有不同的环境中工作 - 或者是有从这个框架供应商建议的方法是什么?
电流控制器实施例:
public function postAction()
{
$json = $this->getRequest()->getContent();
$params = json_decode($json);
$name = $params->name;
$description = $params->description;
$sandbox = new Sandbox();
$sandbox->setName($name);
$sandbox->setDescription($description);
$em = $this->getDoctrine()->getManager();
$em->persist($sandbox);
$em->flush();
$response = new Response('/sandbox/'.$sandbox->getId());
$response->setStatusCode(201);
return $response;
}
目前的试验例:
class SandboxControllerTest extends WebTestCase
{
public function testRest()
{
$client = static::createClient();
$crawler = $client->request('POST', '/service/sandbox', array(), array(), array(), json_encode(array('name' => 'TestMe', 'description' => 'TestDesc')));
$this->assertEquals(
201, $client->getResponse()->getStatusCode()
);
}
}
在我看来,你一定要避免与你的测试更改数据库。
我最喜欢的方式来实现这一目标是注入测试客户端内的实体管理器模拟。 例如:
public function testRest()
{
// create entity manager mock
$entityManagerMock = $this->getMockBuilder('Doctrine\ORM\EntityManager')
->setMethods(array('persist', 'flush'))
->disableOriginalConstructor()
->getMock();
// now you can get some assertions if you want, eg.:
$entityManagerMock->expects($this->once())
->method('flush');
// next you need inject your mocked em into client's service container
$client = static::createClient();
$client->getContainer()->set('doctrine.orm.default_entity_manager', $entityManagerMock);
// then you just do testing as usual
$crawler = $client->request('POST', '/service/sandbox', array(), array(), array(), json_encode(array('name' => 'TestMe', 'description' => 'TestDesc')));
$this->assertEquals(
201, $client->getResponse()->getStatusCode()
);
}
有一件事与此解决方案,你应该知道的是,你需要在每个请求之前注入你嘲笑的服务。 这是因为客户端重新启动每个请求之间的内核(这意味着该容器被重建为好)。
编辑:
在控制器的测试我的GET方法是,我可以为存根从数据库中每一个获取数据嘲笑实体仓库等,但它是一个大量的工作,它不是很舒服,所以我在这种情况下,更喜欢(我的意思是,只有当我们说话关于控制器的测试)实际上正从DB真实的数据。 通过真实的数据我的意思是教义灯具创建的数据。 而只要我们不改变数据库中,我们可以依靠的灯具。
但是,如果我们谈论的内部数据库更改数据(POST / PUT / DELETE方法),我总是用嘲弄。 如果您将使用EM嘲笑,并设置“perist”和“刷新”方法适当的期望,你可以确保数据正确地创建/更新/不包含任何数据库的修改实际删除。
这是我做的
在测试类中添加$内核静态变量,并创建加载内核在测试模式功能
protected static $kernel;
protected static $container;
public static function setUpBeforeClass()
{
self::$kernel = new \AppKernel('test', true);
self::$kernel->boot();
self::$container = self::$kernel->getContainer();
}
而作为测试功能的第一行调用self:setUpBeforeClass()
这使symfony的加载config_test.yml配置文件,您可以定义有不同的数据库连接
要做到这一点,特别是如果你需要在你的数据库中的一些测试数据的一个好方法一起使用一个单独的SQLite数据库与DoctrineFixturesBundle。
- 下面是如何安装FixturesBundle
一个干净的方式来建立你的灯具和测试
请确保你已经在你的PHP激活SQLite的扩展