使用Mockito捕获链式方法中的参数



我正在使用Mockito为现有类编写一些Java单元测试。但是,我在提取参数时遇到了问题,该类的对象使用这些参数作为嵌套调用的一部分来调用方法。

示例:

public class SomeClass {
  public SomeClass() {
    //...
  }
  public someMethod(Foo foo) {
    // Bar bar = ...
    someOtherMethod(bar);
  }
  private someOtherMethod(Bar bar) {
    //...
  }
}

我想捕获someOtherMethod()的参数,并验证bar是否应该是它。我可以使用ArgumentCaptor或Mockito中的其他功能吗?

模拟someOtherMethod不太可能为您提供有用的结果someMethod是您的公共API的一部分,但someOtherMethod不是;通常,测试约定(someMethod的返回值和副作用)很重要,但测试实现(someMethod调用的私有方法)是一个反模式。

  • 理想情况下,只需测试someMethod的结果和副作用,并将其实现视为黑盒。你可能根本不需要使用Mockito。这是最纯粹的测试驱动开发形式:它可以让您自由重构someMethod,可能完全省略对someOtherMethod的调用,或者在不编辑测试的情况下缓存结果(等等)
  • 如果someOtherMethod调用外部服务,请在SomeClass实例上将其设为可访问或可设置的字段,并模拟该服务。与其他服务的互动可以合理地视为一般合同的一部分;这正是Mockito的设计初衷
  • 如果someOtherMethod足够独立,您想单独测试someMethod,请考虑将其打包为私有或受保护。这样,您就可以在测试中,甚至在代码的其他地方,用一个伪实现来覆盖它——毕竟,它现在是someMethod合同的一个测试部分,对吧?如果它太大或不透明,您也可以考虑将其作为一个单独的可模拟类

另请参阅Programmers.SE中的"How do I unit test private methods?",或StackOverflow中的"当我们无法将mock对象传递给类的实例时,如何使用Mockito"。

一个选项是用一个类覆盖SomeClass,该类存储这些参数并使它们可供您验证。一个优雅的选择是自定义参数匹配器。

是。

@Spy
private SomeClass someClassSpy;
@Captor
private ArgumentCaptor<Bar> barCaptor;
...
verify(someClassSpy).someOtherMethod(barCaptor.capture());
Bar bar = barCaptor.getValue();
assertThat(bar, is(...));

相关内容

  • 没有找到相关文章

最新更新