Php 战地失败时创建的条令单元测试

Php 战地失败时创建的条令单元测试,php,unit-testing,symfony,doctrine-orm,Php,Unit Testing,Symfony,Doctrine Orm,我将symfony3与ORM一起使用 我正在测试一个控制器操作,但是断言失败,因为创建的位置不同 public function testGetOneJobFound() { $expected = '{"id":"a961c741-1c32-11ea-bfc6-0242ac130003","service_id":804040,"zipcode_id":"10115","title":"title","description":"decription","date_to_be_done

我将symfony3与ORM一起使用 我正在测试一个控制器操作,但是断言失败,因为创建的位置不同

public function testGetOneJobFound()
{
    $expected = '{"id":"a961c741-1c32-11ea-bfc6-0242ac130003","service_id":804040,"zipcode_id":"10115","title":"title","description":"decription","date_to_be_done":"2018-11-11T00:00:00+00:00","created_at":"2019-12-11T14:55:48+00:00"}';

    $this->client->request('GET', '/job/a961c741-1c32-11ea-bfc6-0242ac130003');

    $this->assertEquals(Response::HTTP_OK, $this->client->getResponse()->getStatusCode());
    $this->assertEquals($expected, $this->client->getResponse()->getContent());
}
单元测试结果: 时间:4.49秒,内存:22.00MB

有1次失败:

1) Tests\AppBundle\Controller\JobControllerTest::testGetOneJobFound
Failed asserting that two strings are equal.
--- Expected
+++ Actual
@@ @@
-'{"id":"a961c741-1c32-11ea-bfc6-0242ac130003","service_id":804040,"zipcode_id":"10115","title":"title","description":"decription","date_to_be_done":"2018-11-11T00:00:00+00:00","created_at":"2019-12-11T14:55:48+00:00"}'
+'{"id":"a961c741-1c32-11ea-bfc6-0242ac130003","service_id":804040,"zipcode_id":"10115","title":"title","description":"decription","date_to_be_done":"2018-11-11T00:00:00+00:00","created_at":"2019-12-11T20:43:36+00:00"}'
正如您所看到的,除了在零件处创建的响应外,响应看起来是相同的


如何从响应中忽略创建的位置。

常见的方法是对内容进行
json\u decode()
然后只比较您感兴趣的数据,例如id、服务id、zipcode\u id等

如果您想实际执行时间敏感测试,例如检查工作何时完成,您可以使用Symfony的PHPUnitBridge之类的工具来“冻结”时间。这不适合WebTestCase,更不适合单元测试。如果要检查创建的时间戳,大致就是这样:

课堂作业
{
公共函数构造()
{
$this->createdAt=DateTime::createFromFormat('U',time());
}
公共函数getCreatedAt():DateTime
{
返回$this->createdAt;
}
}
---
/**
*@组时间敏感
*/
公共函数testJobCreatedAtIsSetToCurrentTime():void
{
$job=新作业();
$this->assertSame(time(),$job->getCreatedAt()->格式('U');
}
如果您希望WebTestCase具有类似的功能,或者您希望测试仅“冻结”特定时间的更复杂场景,那么我能想到的最佳方法是避免使用
DateTime
/
DateTimeImmutable
date()
,相反,它有一个时钟服务,该服务被注入到提供时间的服务中。这需要一些额外的工作和复杂性,但使基于时间的测试更加可靠。有了一个提供时间的服务,就可以用“冰钟”代替它进行测试。有一个你可以使用的库:,但是你可以很容易地写一些更适合你需要的东西。如果我改用库,前一个测试就是这样的:

课堂作业
{
公共功能构造(时钟$时钟)
{
$this->createdAt=$clock->now();
}
公共函数getCreatedAt():DateTimeImmutable
{
返回$this->createdAt;
}
}
---
公共函数testJobCreatedAtIsSetToCurrentTime():void
{
$clock=新的FrozenClock(新的日期时间不可变('2019-12-11T14:55:48+00:00');
$job=新作业();
$this->assertSame('2019-12-11T14:55:48+00:00',$job->getCreatedAt()->格式(DateTime::ATOM));
}

对于
test/services.yaml中的web测试用例,您可以将任何别名为时钟接口的服务更改为具有固定时间的FrozenClock服务,以确保每个需要时钟的服务都使用该时间。

一个选项是转换为阵列,unset创建了_at并进行了比较。@FelippeDuarte我对相同的想法进行了思考,但我不确定这是否是最佳实践