为什么模拟的类不输入未模拟的函数?

时间:2018-07-26 09:32:16

标签: java unit-testing spring-boot mockito

我有课:

@Component
public class GCInitializer
{
    @Autowired
    GCGoodRepository gcGoodRepository;

    @PostConstruct
    public void onStartup() throws Exception
    {
        // load/update base data
        initGCBaseData();
    }

    private void initGCBaseData() throws Exception 
    {
        ArrayList<GCGood> dbGoods;
        ArrayList<GCGood> fileGoods;
        ArrayList<GCGood> baseGoods;

        dbGoods = getGCGoodsFromDB();
        fileGoods = getGoodsFromFile();
        baseGoods = getGoodsFromInitializer();

        // do my merge magic
        […]
    }

    private ArrayList<GCGood> getGoodsFromInitializer() {
        ArrayList<GCGood> baseGoods = new ArrayList<>();
        […]
    }
    […]
}

此类在启动时搜索三个不同的数据源,以获取不同的商品,并将它们组合在一起而不重复。

现在我想用Mockito编写单元测试:

@RunWith(SpringRunner.class)
@SpringBootTest
public class GCInitializerTest {

    @Autowired
    GCGoodRepository gcGoodRepository;

    @Test
    public void onStartupFirstTime() throws InvocationTargetException, IllegalAccessException 
    {
        // normal Start: after Start there are only 7 goods in it!!! (Db far away Off, File empty => only Standards!!!)
        GCInitializer gcInitializer = Mockito.mock(GCInitializer.class);
        Mockito.when(gcInitializer.getGoodsFromFile()).thenReturn(null);
        Mockito.when(gcInitializer.getGCGoodsFromDB()).thenReturn(null);
        ReflectionTestUtils.setField(gcInitializer, "gcGoodRepository", gcGoodRepository);
        gcGoodRepository.deleteAll();

        // private invokation of GCInitializer::initGCBaseData()
        Method method = GCInitializer.class.getDeclaredMethod("initGCBaseData");
        method.setAccessible(true);
        method.invoke(gcInitializer);

        assertEquals(Lists.newArrayList(gcGodRepository.findAll()).size(), 7);
    }
    [...]
}

带有调试器的Runnig永远不会输入函数GCInitializer :: getGoodsFromInitializer()并返回null,而不是具有7个GCGoods的数组。

为什么会这样?我如何才能实现此功能使我获得正确的ArrayList?

2 个答案:

答案 0 :(得分:1)

我同意备忘录,但是如果您愿意,可以使用真实的部分模拟here,例如:

when(mock.someMethod()).thenCallRealMethod();

答案 1 :(得分:0)

这是一个模拟,因此它没有实现实际的方法。您可能要改用间谍。