【问题标题】:Mockito nested calling [duplicate]Mockito嵌套调用[重复]
【发布时间】:2021-12-21 14:57:26
【问题描述】:

我有以下课程:

class LibraryClass implements LibraryInterface {
    @Override
    public void calculate(Order order)
    {
        //some logic
    }
    @Override
    protected void findAll(Order order)
    {
     //some logic
    }

    protected Map resetAllValues(Order order)
    {
     //some logic
    }
    @Override
    protected void sum(order) {//somelogic}
}
class MyCustomClass extends LibraryClass {
    @Override
    public void calculate(Order order)
    {
        findAll(order);

    }

    @Override
    protected void findAll(Order order)
        {
            //some logic
        final Map taxValueMap = resetAllValues(order);

        sum(order);
        }

    @Override
    protected void sum(order)
    {
        int totalCount = getTotalPrice(order);
        int totalItems = getTotalItems(order);
    }
    private int getTotalPrice(Order order) { ...}
    private int getTotalItems(Order order) { ...}
}

LibaryClassLibraryInterface 来自我无法更改的库,并且我已经实现了 MyCustomClass。我的目标是使用 Mockito 来验证 totalCounttotalItems 的值是当我以某种顺序传入计算方法时的某个预期值。

现在我偶然发现了 2 个问题:

  1. resetAllValues(order) - 我想让这个方法用 Mockito 返回一个空映射,但我不能,因为该方法受到保护。如果我不让这个方法返回一个空映射,例如它会尝试进行数据库调用并抛出异常。

  2. 如果我设法做到了 1.,那么我应该如何验证来自私有方法 getTotalPricegetTotalItems 的返回值是否返回正确的值。

【问题讨论】:

  • “如果我不让这个方法返回一个空映射,例如它会尝试进行数据库调用并抛出异常。”。这是在哪里完成的?
  • 这是在 LibraryClass 的 resetAllValues(order) 实现中完成的。
  • @xerx593 这解决了我的第一个问题,但第二个问题仍然存在
  • 2.:通常“没有人测试'非bulic'方法”,因为:它们都(理想情况下在所有(角落)情况下)都被一些“公共(方法)测试”所覆盖! ;) 所以你不会“验证私有”,而是运行多个“公共”(计算()?)测试,“发现私有方法的所有分支”......你将验证(期望/一致性)主要结果(..具有不同的输入/模拟)
  • 2: How do you unit test private methods? -> “你一般不会……” ;)

标签: java mocking mockito


【解决方案1】:

库的创建者可能有理由限制 resetAllValues() 的可见性,但在您的情况下,它禁止您应用 Composition over Inheritance 模式。

所以我要做的是创建LibraryClass 的最小子类,除了使resetAllValues() 可公开访问(或至少在MyCustomClass 的包中可访问)之外什么都不做。这个类“太简单而不能失败”,所以它不需要单元测试

class MyLibraryClass extends LibraryClass {
   @override Map resetAllValues(Order order){
      return super.resetAllValues(order);
   }
}

然后我将这个新类的一个实例注入MyCustomClass

class MyCustomClass implements LibraryInterface {
    private final MyLibraryClass delegate;
    MyCustomClass(MyLibraryClass delegate){
       this.delegate=delegate;
    }
    
    @Override
    public void calculate(Order order)
    {
        findAll(order);
    }

    @Override
    protected void findAll(Order order)
    {
        //some logic
         final Map taxValueMap = elegate.resetAllValues(order);
         sum(order);
    }

    @Override
    protected void sum(order)
    {
        int totalCount = getTotalPrice(order);
        int totalItems = getTotalItems(order);
    }
    private int getTotalPrice(Order order) { ...}
    private int getTotalItems(Order order) { ...}
}

现在 Mockito 可以模拟 MyLibraryClass.resetAllValues()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-03
    • 1970-01-01
    • 2018-04-28
    • 2023-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多