18

我有一个名为 method1 的方法,它接受一个在 myManager 上调用的双精度数,我正在传入这个 65.888 * 60。当我尝试验证这一点时,我遇到了浮点问题。验证失败。它预计 3953.28 但 3953.280029296875

verify(myManager, times(1)).method1(65.888 * 60d);

无论如何我可以让这个验证对浮点检查进行模糊检查。就像你对 assertEquals 所做的一样,你在最后输入一个增量。

谢谢

4

4 回答 4

29

您可以捕获价值,例如

final ArgumentCaptor<Double> captor = ArgumentCaptor.forClass(Double.class)
...
verify(myManager).method1(captor.capture());

然后断言:

assertEquals(expected, captor.getValue(), delta)

或者,也许,使用执行断言的参数匹配器:

verify(myManager).method1(doubleThat(new ArgumentMatcher<Double>() 
{
    @Override 
    public boolean matches(final Object actual)
    {
        return Math.abs(expected - (Double) actual) <= delta;
    }
}));

更新:

除了使用上述任何一种方法,您还可以使用AdditionalMatchers.eq(double, double),例如:

verify(myManager).method1(AdditionalMatchers.eq(expected, delta));

尽管AdditonalMatchers根据文档明智地使用匹配器:

AdditionalMatchers 提供了很少使用的匹配器,只是为了与 EasyMock 兼容而保留。非常明智地使用额外的匹配器,因为它们可能会影响测试的可读性。建议使用 Matchers 中的匹配器,并保持存根和验证简单。

于 2013-05-02T10:59:06.753 回答
9

有一个 Hamcrest 匹配器非常适合这个。

org.hamcrest.Matchers.closeTo(value, error)

所以你可以写类似

verify(myManager).method1(doubleThat(org.hamcrest.Matchers.closeTo(65.888 * 60, 0.001)));

顺便说一句,您永远不需要times(1)在 Mockito中编写,因为这是Mockito 为您提供verify的默认类型。verify

于 2013-05-03T06:05:55.857 回答
1

以下代码对我有用:

private class MockedClass {
    public void method1(double d) {}
}

@Test
public final void testMockito() {
    MockedClass d = mock(MockedClass.class);
    d.method1(3953.28);
    verify(d, times(1)).method1(65.888 * 60d);
}

也许您应该改为使用 anyDouble() 调用该方法或使用以下匹配器:http: //hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/number/IsCloseTo.html

于 2013-05-02T11:44:13.557 回答
0

如何使用:

when(65.888).thenReturn(65.888 * 60);

assertEquals(65.888 * 60, new BigDecimal(Double.toString(65.888 * 60))
    .setScale(pRoundingDecimalPlaces, 2).doubleValue());
于 2016-02-15T06:44:05.570 回答