1

我有以下代码(Facade 的一小部分)要在单元测试中覆盖。我正在使用 Mockito 来模拟属于服务层的函数。

Iterator<AbstractOrderEntryModel> entryModelItr = orderEntryModelList.iterator();
            while (entryModelItr.hasNext()) {

                AbstractOrderEntryModel entryModel = entryModelItr.next();

                if (CollectionUtils.isNotEmpty(deletedPKList) && deletedPKList.contains(entryModel.getPk().toString())) {
                    entryModelItr.remove();
                    modelService.remove(entryModel);
                }

            }

我一直在通过调用要测试的函数并提供具有设定值的输入来编写测试用例,以便可以实现代码的最大覆盖率(如果这不是它应该完成的方式,请纠正我)。

我的问题是我有entryModel.getPk()没有设置器的功能,例如。entryModel.setPk()我可以打电话。结果,它将在此行中引发空指针异常。我不想嘲笑这个entryModel对象。怎么办?

Pk就像那个模型类的 PrimaryKey。整个代码是在 Hybris 平台上编写的)

4

2 回答 2

2

如果你用一个真实的对象测试一个真实的系统,那么缺少主键将会产生真正的后果。你最好的测试“接缝”是覆盖你的模型类,提取你对它的调用,这样你就可以将它外部化,或者监视一个真实的对象。我强烈建议在重构时考虑到测试,但您确实有一些选项在生产中的影响为零或最小。


一种解决方案是创建您自己的 AbstractOrderEntryModel 的具体子类,大概称为 FakeOrderEntryModel,它具有您想要的构造函数。我认为这是这里最好的方法,特别是因为它不会改变被测系统。

另一个需要最少更改的解决方案是在您的被测系统上提取entryModel.getPk().toString()到一个可覆盖的方法。protected在您的测试中,覆盖该方法以提供基于地图的查找。一个重 OOP 的解决方案是在策略模式中创建一个“PkGetter”类(使用单一getPk(AbstractOrderEntryModel model)方法)并为测试提供替代实现;这可能是矫枉过正。

最后,要使用真实的数据对象但只覆盖其上的一两个方法,请使用spy

AbstractOrderEntryModel model = spy(new ConcreteOrderEntryModel(...));
doReturn(42).when(model).getPk();
于 2015-05-17T22:01:17.733 回答
0

鉴于这个问题已有 5 年历史,如果有人仍然好奇 Jeff Bowman 的上述解决方案是否有效,以下对我有用。

private AbstractOrderEntryModel abstractOrderEntryModel = new AbstractOrderEntryModel (){
    @Override
    public PK getPk() {
        return de.hybris.platform.core.PK.BIG_PK;
    }
};

猜猜我在监视模型对象时做错了什么,但是,覆盖 getPk() 方法对我有用。

于 2020-11-30T11:18:43.930 回答