使用Mockito检查多个参数的一致性

16

我正在使用Mockito来mock一个带有类似以下方法的类:

setFoo(int offset, float[] floats)
我希望能够验证数组(floats)中的值是否与预期值数组中的值相等(在给定的公差范围内)。问题是,我想要检查从指定位置 offset 开始的 floats 的内容。对于测试目的,我不知道/不关心偏移量是多少,只要它指向我期望的值即可。我也不关心数组的其余部分包含什么。我只关心从提供的偏移量开始的值。如何实现这一点?

也许只是我,但我不太理解你的问题。编写自己的方法需要偏移量和2个数组作为参数,并检查从偏移量开始这些数组中的元素是否相等,这有什么问题吗? - Andrew Logvinov
@AndrewLogvinov 我该如何在 Mockito 的模拟对象上“编写自己的方法”? - Laurence Gonsalves
我认为你甚至不应该这样做。在调用 setFoo() 后,您期望对象的状态已更改。因此,您应查询对象的状态并将其与您的值进行比较。一些代码片段将有助于更好地理解问题。 - Andrew Logvinov
被模拟的类处理硬件。对于这个“set”方法没有相应的“get”。这就是为什么我要将其模拟化。 - Laurence Gonsalves
请提供一些代码,这样帮助会更加容易。 - Dan
2个回答

49

虽然部分模拟不是一个坏主意,但是如果您使用ArgumentCaptor来在实际值获取后获取值,您可能会发现代码更容易跟踪。它是一个特殊的参数匹配器,可以跟踪匹配的值。

// initialized with MockitoAnnotations.initMocks();
@Captor ArgumentCaptor<Integer> offsetCaptor;
@Captor ArgumentCaptor<float[]> floatsCaptor;
@Mock Bar bar;

@Test
public void valuesShouldBeCloseEnough() {
  Sut sut = new Sut(bar);
  sut.doSomething();
  verify(bar).setFoo(offsetCaptor.capture(), floatsCaptor.capture());

  // check values with assertValuesAreCloseEnough, declared elsewhere
  assertValuesAreCloseEnough(offsetCaptor.getValue(), floatsCaptor.getValue());
}

这正是我所需要的。谢谢! - Laurence Gonsalves

1
你想要一个部分模拟。假设有一个名为Bar的类,其中包含setFoo()方法:
private static abstract class AssertingBar implements Bar {

  @Override
  void setFoo(int offset, float[] floats) {
    this.offset = offset;
    this.floats = floats
  }

  public void verify(float[] expectedFloats, float delta) {
    // do your verification here
  }
}

@Test
public void valuesShouldBeCloseEnough() {
  AssertingBar bar = Mockito.mock(AssertingBar.class, Mockito.CALLS_REAL_METHODS);

  Sut sut = new Sut(bar);
  sut.doSomething();

  bar.verify(...); 
}

如果Bar是一个类而不是接口,那么你可以使用doCallRealMethod()

Mockito.CALLS_REAL_METHODS 似乎无法与接口一起使用。我不断收到关于在接口上调用真实方法的错误。我尝试使用 doCallRealMethod() 取得了一些进展,但另一个答案中建议的参数捕获方法更容易实现,并且对于这种特殊情况需要的代码要少得多。无论如何,还是谢谢。 - Laurence Gonsalves

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接