【问题标题】:Mocking getPk() function when there is no setPk()没有 setPk() 时模拟 getPk() 函数
【发布时间】:2015-05-17 17:40:29
【问题描述】:

我有以下代码(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 平台上编写的)

【问题讨论】:

  • 您是如何创建entryModel 的?不能在构造函数中提供PK吗?
  • 不,没有为entryModel 编写的这样的构造函数。假设我无法更改要测试的代码。它是由没有时间为其编写单元测试的其他人编写的。
  • 我正在创建一个列表 orderEntryModelList,其中有一个元素,我再次创建并添加了 - entryModel。如果有 Pk 的设置器,我会在其中设置一些值。

标签: unit-testing junit mockito hybris powermockito


【解决方案1】:

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


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

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

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

AbstractOrderEntryModel model = spy(new ConcreteOrderEntryModel(...));
doReturn(42).when(model).getPk();

【讨论】:

  • 感谢您提供的详细答复。我想我会去监视真实的对象。我还有一个疑问。您在“Finally..”之后写的解决方案与您在上面写的内容无关吗?
  • 对。监视模型对象会起作用,但请记住,间谍是真实对象的副本,而不是对它们的视图:您需要确保可以将间谍传递到被测系统中。
【解决方案2】:

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

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

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

【讨论】:

    猜你喜欢
    • 2022-07-25
    • 2017-11-17
    • 2023-03-17
    • 2013-11-04
    • 2017-09-02
    • 1970-01-01
    • 1970-01-01
    • 2014-11-27
    • 1970-01-01
    相关资源
    最近更新 更多