单元测试默认方法在接口中调用抽象方法

时间:2018-04-04 18:45:09

标签: java spring-boot junit interface mockito

我有一个接口,它有两个方法 - convertList和convert。

convertList有一个默认实现,为其inputList中的每个输入调用convert

我想为convertList写一个单元测试 -

  • 测试它是否调用convert方法的次数与inputlist的大小相同
  • 测试是否将每个输入的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);
        }
    }
}

我在模拟界面和存根转换方法时无法实现1。以下是我的测试课程。

@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");
        }
    }
}

以下是我得到的错误

  

想要但未被调用:myConverter.convert(myDTO,&#34; 1234&#34;);    - &GT;在com.abc.project.converters.MyConverterTest.testConvertListOfSizeOne(MyConverterTest.java:49)

     

但是,还有其他与此模拟的交互:   myConverter.convertList(       [myDTO]       &#34; 1234&#34; );

1 个答案:

答案 0 :(得分:0)

有两件事帮我解决了这个问题。

一,添加一个实现MyConverter接口的内部类,只需使用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的默认实现。