【问题标题】:Mock and Test method that contains call to final class that contains static and non static methods Java包含对包含静态和非静态方法 Java 的最终类的调用的模拟和测试方法
【发布时间】:2021-04-01 15:29:54
【问题描述】:

我有一个遗留代码,其中包含我要测试的以下方法。如果我删除 Collections.sort 行,那么测试用例就可以正常工作。但我正在尝试用它来执行测试用例。

void update(){
   <!-- Other logic-->
      Collections.sort(demographicsForms, DemographicsFormComparator.getInstance()); 
   <!-- Other logic-->
}

demographicsForms 是一个包含基本 setter 和 getter 的 Pojo 类

DemographicsFormComparator包含以下代码

public final class DemographicsFormComparator implements Comparator<DemographicsForm> {

    public int compare(DemographicsForm demo1, DemographicsForm demo2) {
        return demo1.getType().getCdfMeaning().compareTo(demo2.getType().getCdfMeaning());
    }

    private static DemographicsFormComparator INSTANCE = null;

    public synchronized static DemographicsFormComparator getInstance() {
        if (INSTANCE == null) {
            INSTANCE = new DemographicsFormComparator();
        }
        return INSTANCE;
    }
}

到目前为止,我已经尝试过了

    @Mock
    private DemographicsForm df1;
    @Mock
    private DemographicsForm df2;
    
    @Test
    public void test() {
        final DemographicsFormComparator mockA = PowerMock.createMock(DemographicsFormComparator.class);
        EasyMock.expect(mockA.compare(df1, df2)).andReturn(1).anyTimes();
        PowerMock.mockStatic(DemographicsFormComparator.class);
        EasyMock.expect(DemographicsFormComparator.getInstance()).andReturn(mockA).anyTimes();
        PowerMock.replayAll(mockA);
    }

但上述方法给了我以下错误

java.lang.AssertionError: 
  Unexpected method call DemographicsFormComparator.compare

编辑 1: 尝试为人口统计形式传递真实对象

    DemographicsForm df1 = new DemographicsForm();
        DemographicsForm df2 = new DemographicsForm();

        final DemographicsFormComparator mockA = PowerMock.createMock(DemographicsFormComparator.class);
        EasyMock.expect(mockA.compare(df1, df2)).andReturn(1).anyTimes();

        PowerMock.mockStatic(DemographicsFormComparator.class);
        EasyMock.expect(DemographicsFormComparator.getInstance()).andReturn(mockA).anyTimes();

        PowerMock.replayAll();

仍然接到compare的意外电话

【问题讨论】:

  • 为什么你需要任何个模拟框架呢?创建demographicsForms 的两个真实实例,将它们传递给update 方法,断言update 方法的副作用。除非你在 update 中显示“其他逻辑”——这很重要,这很难回答
  • 其余代码包含可以轻松模拟和测试的更新逻辑,但由于我的代码包含这一行,因此模拟失败。如果我只是尝试传递对象,它将抛出Null Pointer exception for compare method。
  • NullPointer 表明您传递到 update 的对象没有应该存在的字段。从return demo1.getType().getCdfMeaning().compareTo(demo2.getType().getCdfMeaning())看不明显吗?
  • 我也试过这个when(df1.getType()).thenReturn(codevalue); when(codevalue.getCdfMeaning()).thenReturn("test"); when(df2.getType()).thenReturn(codevalue1); when(codevalue1.getCdfMeaning()).thenReturn("test");
  • getType() 为codevalue 返回一个对象,其中还包含getCdfMeaning()

标签: java junit mockito powermock easymock


【解决方案1】:

您有多种可能性。它们都没有涉及 PowerMock。

  1. 填写真实的DemographicsForm,以便它们与比较器一起使用。在您的情况下,吸气剂似乎太复杂了,所以它不起作用
  2. 部分模拟 DemographicsForm 以便模拟烦人的吸气剂
  3. 将比较器移动到字段以注入它

public class MyClass {
     private final Comparator<DemographicsForm> comparator;
     public MyClass(Comparator<DemographicsForm> comparator) {
        this.comparator = comparator;
     }
     public MyClass() {
        this(DemographicsFormComparator.getInstance());
     }
     void update() {
         <!-- Other logic-->
         Collections.sort(demographicsForms, comparator); 
         <!-- Other logic-->
     }

这样您就可以轻松地模拟比较器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-09-04
    • 1970-01-01
    • 2011-12-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多