模拟对象单元测试有问题

时间:2015-10-07 03:10:07

标签: java eclipse easymock

我正在使用模拟对象,我在设置单元测试时遇到问题,该单元测试检查列表是否正确排序。这样做的好处是我正在嘲笑一个时钟,但是简单地使用times()方法是行不通的。列表应按升序排列,但获取第一个索引只会返回最后设置的值。

作为参考,这是一个工作模拟测试,用于测试午夜设置的时钟:

@Test
public void shouldSetAtMidnight() {
    expect(mock.instant()).andReturn(Instant.from(this.midnight));

    expect(mock.getZone()).andReturn(this.timeZone);

    replay(mock);

    this.st.setDesiredValue(72);
    SetPoint[] sched = this.st.getSchedule();

    verify(mock);

    assertEquals(LocalTime.MIDNIGHT, sched[0].getScheduledTime());
}

在这里,设置所需的值非常重要,因为它将SetPoint添加到数组中(setDesiredValue创建一个具有int和LocalTime的SetPoint)。这是我遇到困难的地方:

@Test
public void shouldOrderTwoSetPointsAddedOutOfOrder() {
    expect(mock.instant()).andReturn(Instant.from(this.midnight)).times(2);

    expect(mock.getZone()).andReturn(this.timeZone).times(2);

    replay(mock);

    this.st.setDesiredValue(73);
    this.st.setDesiredValue(71);
    SetPoint[] schedule = this.st.getSchedule();

    verify(mock);

    assertEquals(71, schedule[0].getTemp());
}

setDesiredValue应该将int值与LocalTime相关联,在这种情况下应该是午夜。然后,它将具有这些特征的SetPoint添加到列表中,并调用Collection的sort()方法从最低到最高对它们进行排序。现在,我假设我的问题在于我将两个值与完全相同的时间相关联,尽管两个期望的调用时间(2),但我最近刚开始使用模拟对象而只是不知道他们知道从哪里开始。运行此测试将返回73而不是71。

1 个答案:

答案 0 :(得分:1)

你的假设是正确的。当您说.andReturn(Instant.from(this.midnight)).times(2)时,传递给.andReturn的确切值会重复两次。

你可以做.andReturn(Instant.from(this.midnight)).andReturn(Instant.from(this.midnight)),这会给你两个瞬间。但作为一般规则,这对于单元测试来说是非常糟糕的形式。 Instant.from(this.midnight)来自测试之外,因此您无法预测调用此函数两次是否会产生相同的值或不同的值,从而使测试不确定。好的进行集成测试,不适合进行单元测试,你会使用模拟测试。最好使用实数,例如.andReturn(Instant.fromEpochSecond(10)).andReturn(Instant.fromEpochSecond(15))

您未提供有关st的大量详细信息以及您认为测试不应返回73而不是71的任何原因。