Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/368.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Mockito单元测试-时间戳不同_Java_Unit Testing_Mockito - Fatal编程技术网

Java Mockito单元测试-时间戳不同

Java Mockito单元测试-时间戳不同,java,unit-testing,mockito,Java,Unit Testing,Mockito,Mockito测试有一些问题 我当前遇到以下错误: Argument(s) are different! Wanted: repository.save( uk.co.withersoft.docservice.repositories.hibernate.MetaDataEntity@3e437e6c ); -> at uk.co.withersoft.docservice.datastore.impl.MetaDataStoreImplTest.storeClaimMetada

Mockito测试有一些问题

我当前遇到以下错误:

Argument(s) are different! Wanted:
repository.save(
    uk.co.withersoft.docservice.repositories.hibernate.MetaDataEntity@3e437e6c
);
-> at uk.co.withersoft.docservice.datastore.impl.MetaDataStoreImplTest.storeClaimMetadata(MetaDataStoreImplTest.java:55)
Actual invocation has different arguments:
repository.save(
    uk.co.withersoft.docservice.repositories.hibernate.MetaDataEntity@3e361ee2
);
我很确定这是因为
MetaDataEntity
中的时间不同

//这是我应该得到的

id = null
metaData = "{"caseReference":"CN00000001","claimReference":"LN00000001","rpsDocumentType":"REJ","documentTitle":"Claims LN00000001 (Claimant: Mr LOCAL HOST) REJ-Rejection letter"}"
batchId = 0
state = "Saved MetaData to DB"
lastUpdatedDate = {Timestamp@1517} "2018-07-25 18:39:21.993"
createdDate = {Timestamp@1518} "2018-07-25 18:39:21.993"
//这就是我得到的

id = null
metaData = "{"caseReference":"CN00000001","claimReference":"LN00000001","rpsDocumentType":"REJ","documentTitle":"Claims LN00000001 (Claimant: Mr LOCAL HOST) REJ-Rejection letter"}"
batchId = 0
state = "Saved MetaData to DB"
lastUpdatedDate = {Timestamp@1530} "2018-07-25 18:39:49.274"
createdDate = {Timestamp@1531} "2018-07-25 18:39:52.716"
以下是我的测试用例:

@Test
    public void storeClaimMetadata () throws JsonProcessingException {

        ClaimMetaData metaData = constructMetaData();

        MetaDataEntity mockResponseMetaDataEntity = new MetaDataEntity();
        mockResponseMetaDataEntity.setId(1);

        when(repository.save(any(MetaDataEntity.class))).thenReturn(mockResponseMetaDataEntity);

        Integer result = testSubject.storeClaimMetadata(metaData);

        assertEquals(Integer.valueOf(1), result);

        final ObjectMapper mapper = new ObjectMapper();
        String jsonMetaData = mapper.writeValueAsString(metaData);

        MetaDataEntity expectedMetaDataEntity = new MetaDataEntity(null,
                                                                   jsonMetaData,
                                                                   0,
                                                                   "Saved MetaData to DB",
                                                                   new Timestamp(System.currentTimeMillis()),
                                                                   new Timestamp(System.currentTimeMillis()));

        Mockito.verify(repository, times(1)).save(expectedMetaDataEntity);
    }

    //Creates a ClaimRequest
    private ClaimMetaData constructMetaData() {
        final ClaimMetaData metaData  = new ClaimMetaData("CN00000001",
                                                          "LN00000001",
                                                          "REJ",
                                                          "Claims LN00000001 (Claimant: Mr LOCAL HOST) REJ-Rejection letter");

        return metaData;
    }
任何帮助都将不胜感激。这让我快发疯了

这是“按设计工作”

您正在调用一个计算时间戳的服务。比如现在

然后,您就有了一个测试用例,该测试用例正在进行一些设置,并获取时间戳。现在

猜猜看:尽管上面这两个“现在”彼此很接近,但它们之间还是有一点延迟

如果您正在检查是否相等,只能在时间戳相同的情况下才起作用!但它们不是,因为它们是一个接一个地创建的,其间有非常明显的延迟

意思:您需要了解如何控制在应用程序中创建的时间戳,比如说“时间戳应该是t1和t2”。这样您的测试就可以检查“我找到了t1和t2”


或者,您只需更改验证步骤:您可以比较那些应该相等的部分,而不是尝试拥有“相等”的对象(因为时间戳不同而不能相等!),对于时间戳,您可以检查它们是否“足够接近”“

这正是人们使用依赖注入的原因,因此他们可以指定返回可预测结果的测试协作者。用调用
Timestamp.from(Instant.now(clock))
替换硬编码的
新时间戳(System.currentTimeMillis)
填充

java.time.Clock
是一个可用于获取时间戳值的接口。可以使用返回系统时钟的工厂方法之一(使用SpringJava配置)将真正的实现注入正在测试的代码中:

对于测试代码,您可以有一个实现,其中您可以指定希望时钟返回的时间:

@Before 
public void setUp() {
    clock = Clock.fixed(date.toInstant(), ZoneId.of("America/NewYork"));
    systemUnderTest.setClock(clock);
}

在代码中,您可以使用
新时间戳(DateTimeUtils.currentTimeMillis())
。这里的DateTimeUtils来自jodatime

在测试用例中,可以使用以下命令

private SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss:SSS");

    @Before
    public void before() throws Exception {
        // define a fixed date-time
        Date fixedDateTime = DATE_FORMATTER.parse("01/07/2016 16:45:00:000");
        DateTimeUtils.setCurrentMillisFixed(fixedDateTime.getTime());
    }

    @After
    public void after() throws Exception {
        // Make sure to cleanup afterwards
        DateTimeUtils.setCurrentMillisSystem();
    }````

创建采用LocalDateTime或Timestamp的重载方法;现在让假定的方法调用它。现在,您的测试每次都可以用正确的时间戳实例化一个期望值。或者不要在equals和hashCode方法中包含时间戳。@GhostCat控制时间戳的最佳方法是什么?谢谢你到目前为止的建议!我不知道时钟的事。好主意@幽灵猫没问题,你的解释很完美:)
private SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss:SSS");

    @Before
    public void before() throws Exception {
        // define a fixed date-time
        Date fixedDateTime = DATE_FORMATTER.parse("01/07/2016 16:45:00:000");
        DateTimeUtils.setCurrentMillisFixed(fixedDateTime.getTime());
    }

    @After
    public void after() throws Exception {
        // Make sure to cleanup afterwards
        DateTimeUtils.setCurrentMillisSystem();
    }````