繁体   English   中英

测试根据输入调用内部方法的公共方法

[英]Test public method that calls internal methods depending on input

因此,我们这里有此方法,系统的其余部分可以访问该方法,该方法根据输入调用基础方法。

public SomeReturnObj doSomethingWithInputs(List<Input> inputs) {
  for(Input input : inputs) {
    if(input.getName().equals("A") {
        handleAInput(input);
    }
    else if(input.getName().equals("B") {
        handleBInput(input);
    }
    else { ... }
  }

  // ...
}

为了获得良好的代码覆盖率,我想测试一下,如果我放置一个包含两个名称为A Inputs和三个名称为B Inputs的列表,则相应的内部方法分别被调用两次或三次。

因此,我尝试了以下方法:

@Test
public void separatingInputsByName() {
    Input entry1 = mock(Input .class);
    Input entry2 = mock(Input .class);
    Input entry3 = mock(Input .class);

    doReturn("A").when(entry1).getName();
    doReturn("A").when(entry2).getName();
    doReturn("B").when(entry3).getName();

    ClassUnderTest sut = mock(ClassUnderTest .class);

    sut.doSomethingWithInputs(Arrays.asList(entry1, entry2, entry3));

    verify(sut).handleAInput(entry1);
    verify(sut).handleAInput(entry2);
    verify(sut).handleBInput(entry3);
}

不幸的是,这可能无法正确调用内部方法,这可能是因为被测类是模拟的,因此方法的实现是不同的。

如何正确测试/验证类似方法?

您应该使用spy() ,而不是mock()

当您使用mock() ,所有方法都被“重写”,因此将采取默认操作,而不是调用实际方法。 spy()将仅注册方法调用。

因此:

ClassUnderTest sut = spy(new ClassUnderTest(...));

sut.doSomethingWithInputs(Arrays.asList(entry1, entry2, entry3));

verify(sut).handleAInput(entry1);
verify(sut).handleAInput(entry2);
verify(sut).handleBInput(entry3);
verifyNoMoreInteractions(sut); // if necessary

另外,您可以:

when(entry1.getName()).thenReturn("A");

就我个人而言,我觉得它更容易阅读,但这当然是一个品味问题。

另外,您可以在以下情况下使用InOrder

final InOrder inOrder = inOrder(sut);

inOrder.verify(sut).handleAInput(entry1);
// etc

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM