【问题标题】:EasyMock Unexpected method call expected: 1, actual: 2 java.lang.AssertionError:EasyMock 意外的方法调用预期:1,实际:2 java.lang.AssertionError:
【发布时间】:2017-05-11 07:58:43
【问题描述】:

试图测试一个方法,该方法接受一个对象列表并返回一个排序的对象列表。排序基于将第一个元素放在具有空字符串值的列表中。测试失败并出现以下错误:

java.lang.AssertionError: 
Unexpected method call LoggerConfig.getName():
LoggerConfig.getName(): expected: 1, actual: 2

这里的问题是需要明确的调用次数。这里似乎方法被调用太频繁,这会抛出该方法被调用太多次的异常。在第一个超过限制的方法调用时立即发生故障(取自EasyMock 指南)。 问题是如何在这种情况下解决它?我哪里做错了?

EasyMock 代码:

public class SorterTest {
private Sorter tested;
LoggerConfig item1;
LoggerConfig item2;
LoggerConfig item3;
List<LoggerConfig> sortedList;

@Before
public void setUp() {
    tested = new Sorter();
}

private List<LoggerConfig> makeUnsortedList() {
    item1 = EasyMock.mock(LoggerConfig.class);
    item2 = EasyMock.mock(LoggerConfig.class);
    item3 = EasyMock.mock(LoggerConfig.class);

    EasyMock.expect(item1.getName()).andReturn("com.core");
    EasyMock.expect(item2.getName()).andReturn("");
    EasyMock.expect(item3.getName()).andReturn("com.core.FOO");

    List<LoggerConfig> unsortedList = new ArrayList<>();
    unsortedList.add(item1);
    unsortedList.add(item2);
    unsortedList.add(item3);


    return unsortedList;
}

@Test
public void testSort() {

    List<LoggerConfig> unsortedList = makeUnsortedList();
    EasyMock.replay(item1,item2,item3);

    List<LoggerConfig> sortedList = tested.sort(unsortedList);

    assertTrue(sortedList.get(0).getName().isEmpty());
    assertTrue(sortedList.get(1).equals("com.core") || sortedList.get(1).equals("com.fwk.core.EBCTestClass"));
    assertTrue(sortedList.get(2).equals("com.core") || sortedList.get(2).equals("com.core.FOO"));

}

}

测试以下方法:

class Sorter {

  List<LoggerConfig> sort(List<LoggerConfig> unSortedList) {

    List<LoggerConfig> sortedList = new ArrayList<>(unSortedList);

    Collections.sort(sortedList, new Comparator<LoggerConfig>() {
        @Override
        public int compare(LoggerConfig o1, LoggerConfig o2) {
            return (o1.getName().compareTo(o2.getName()));
        }
    });

    return sortedList;
  }
}  

【问题讨论】:

    标签: java easymock


    【解决方案1】:

    它调用getName() 作为排序的一部分(可能多次,具体取决于算法),然后在您的验证中再次调用。由于您对它被调用的次数并不真正感兴趣(因为它不是您测试合同的一部分),所以删除默认限制。为此,请将andReturn 替换为andStubReturn:

    EasyMock.expect(item1.getName()).andStubReturn("com.core");
    EasyMock.expect(item2.getName()).andStubReturn("");
    EasyMock.expect(item3.getName()).andStubReturn("com.core.FOO");
    

    【讨论】:

    • 所有建议都不允许测试通过。 niceMock 选项给出Nullpointer 异常。 andStubReturn 给出第一个断言 assertTrue(sortedList.get(0).getName().isEmpty()); 的错误。此行失败意味着此处或实际实现中的问题?
    • 这已经解决了这个问题,并在单元测试中做了一些改动。 assertTrue(sortedList.get(1).equals("com.core") 缺少方法调用 getName() 并且只传递了无法比较的对象。修复是assertTrue( sortedList.get(1).getName().equals("com.core")
    • @shaz 我已纠正;正如您所注意到的,漂亮的模拟并不是这里的答案。您需要对方法进行存根,以便每次调用都返回预期值,并且在预期的调用次数 (1) 之后不会恢复为“良好”(null-return)行为。
    【解决方案2】:

    andStubReturn 确实是当您不知道(也不在乎)一个方法将被调用多少次时要走的路。

    我想补充一点,我发现你的断言有点奇怪。你知道排序的确切结果。此外,不建议在断言部分调用模拟的方法。相反,您可以这样做:

    assertSame(item2, sortedList.get(0));
    assertSame(item1, sortedList.get(1));
    assertSame(item3, sortedList.get(2));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-06
      • 2018-10-23
      相关资源
      最近更新 更多