我有一个接口(interface),它有两个方法 - ConvertList 和 Convert。
convertList
有一个默认实现,它会为其 inputList 中的每个输入调用 convert
。
我想为 ConvertList 编写一个单元测试 -
- 测试调用convert方法的次数是否与输入列表的大小相同
- 测试它是否将每个输入的convertedOutput对象传递到convertedOutputs列表
以下是我的界面 -
public interface MyConverter {
ConverterOutput convert(final MyDTO input, final String myParam) throws MyDTOConversionException;
default Collection<ConverterOutput> convertList(
final Collection<? extends MyDTO> inputList,
final String myParam)
throws MyDTOConversionException {
try {
List<ConverterOutput> converterOutputs = new ArrayList<>();
for (MyDTO input : inputList) {
converterOutputs.add(this.convert(input, myParam));
}
return converterOutputs;
} catch (NullPointerException npe) {
throw new MyDTOConversionException("Unable to convert dto to converter output", npe);
}
}
}
在模拟接口(interface)并 stub 其转换方法时,我无法实现 1。以下是我的测试类(class)。
@SpringBootTest(classes = MyConverter.class)
public class MyConverterTest extends BaseTest {
class MyDTOImpl extends MyDTO {
@Override
public void someAbstractMethod(String param) {
}
}
@Mock
private ConverterOutput converterOutput;
@Mock
private MyConverter myConverter;
@Mock
private MyDTOImpl myDTO;
@Test
public void testConvertListOfSizeOne() {
String myParam = "1234";
Collection<MyDTO> myDTOS = new ArrayList<>();
myDTOS.add(myDTO);
try {
when(myConverter.convert(myDTO, myParam)).thenReturn(converterOutput);
Collection<ConverterOutput> actualConverterOutputs = myConverter.convertList(myDTOS, myParam);
// check if times convert method was called is as expected
verify(myConverter, times(1)).convert(myDTO, myParam);
// check if number of items in output object are as expected
Assert.assertEquals(actualConverterOutputs.size(), 1);
// check if output object is as expected
for (ConverterOutput c: actualConverterOutputs) {
Assert.assertSame(c, converterOutput);
}
} catch (MyDTOConversionException exception) {
throw new AssertionError("MyDTOConversionException should not have occurred");
}
}
}
以下是我遇到的错误
Wanted but not invoked: myConverter.convert(myDTO, "1234"); -> at com.abc.project.converters.MyConverterTest.testConvertListOfSizeOne(MyConverterTest.java:49)
However, there were other interactions with this mock: myConverter.convertList( [myDTO], "1234" );
最佳答案
有两件事帮助我解决了这个问题。
一,添加一个实现 MyConverter 接口(interface)的内部类,因为简单地使用 Mock 注释似乎也覆盖了默认方法,并且我无法要求 Mockito 调用原始默认方法实现。
class MyConverterImpl implements MyConverter {
MyConverterImpl() {}
@Override
public ConverterOutput apply(final MyDTO input, final String myParam)
throws MyDTOConversionException {
return converterOutput;
}
}
接下来,明确要求 Mockito 调用真正的方法
when(myConverter.convertList(myDTOS, myParam)).thenCallRealMethod();
如果没有这个,convertList 的默认实现就不会被调用。
关于java - 单元测试默认方法调用接口(interface)中的抽象方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49658257/