EasyMock "Unexpected method call" 尽管有 expect 方法声明

EasyMock "Unexpected method call" despite of expect method declaration

我的 EasyMock 预期方法被认为是意外的,虽然我没有使用和严格模拟,并且该方法在被回复之前已经声明。

这行代码测试失败:

Intent batteryIntent = context.getApplicationContext().registerReceiver(null,
        new IntentFilter(Intent.ACTION_BATTERY_CHANGED));

测试:

@Before
public void setUp() {
    mocksControl = createControl();
    contextMock = mocksControl.createMock(Context.class);
    //(...)
}

@Test
public void test() {
    expect(contextMock.getApplicationContext()).andReturn(contextMock).anyTimes();
    expect(contextMock.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)))
        .andReturn(someIntent1).once();
    expect(contextMock.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)))
        .andReturn(someIntent2).once();
    mocksControl.replay();
    //(...) tested method is invoked on class under the test
}

我得到的错误:

java.lang.AssertionError: 
  Unexpected method call Context.registerReceiver(null, android.content.IntentFilter@c009614f):
    Context.registerReceiver(null, android.content.IntentFilter@c009614f): expected: 1, actual: 0
    Context.registerReceiver(null, android.content.IntentFilter@c009614f): expected: 1, actual: 0

默认情况下,EasyMock 使用相等匹配器。所以这意味着IntentFilter参数将使用equals进行比较。

我不确定是否在 IntentFilter 上编写了有效的 equals。查看文档,可能并非如此。所以这就是为什么没有匹配项。

唯一令人惊讶的是,IntentFilter上用来显示错误信息的toString是Object之一。这三个都有相同的地址(c009614f)。这很奇怪,因为这意味着它们都是同一个实例。这是不可能的。所以我会坚持我的回答。

要修复它,取决于您是否真的关心参数,您可以使用 anyObject() 或专用比较器

当你写类似的东西时,

expect(contextMock.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED)))
        .andReturn(someIntent1).once();

Easymock 期望 registerReceiver 方法使用被告知期望的确切参数来调用,

因此,为了避免这种情况,在期望任何方法并编写其行为的同时,使用 anyObject() 方法,如下所示:-

expect(contextMock.registerReceiver(null, EasyMock.anyObject(IntentFilter.class)))
            .andReturn(someIntent1).once();

由此,当 IntentFilter 的任何对象作为参数传递时,easymock 明白它必须模拟对预期方法的所有调用

希望对您有所帮助! 祝你好运!

我最近遇到了类似的问题。 我注意到 Easymock 不允许混合类型。 所有参数必须使用相同类型的策略。

记录方法时匹配器与原始值混合时通常会出现此异常:

foo(5, eq(6));  // wrong

您不能完全使用匹配器或对每个参数都使用匹配器:

foo(eq(5), eq(6));  // right

foo(5, 6);  // also right

对于运行关注此问题的人,请注意在测试中调用源代码方法的次数应等于 expect 设置的次数。

例如:如果在测试代码中设置了如下期望,

expect(contextMock.registerReceiver(null, EasyMock.anyObject(IntentFilter.class)))
        .andReturn(someIntent1).once();

也就是说,当测试代码为运行时,它应该恰好有1次调用registerReceiver方法。否则,我们最终会得到不同的断言异常,如下所示:

java.lang.AssertionError: 
  Unexpected method call Context.registerReceiver(null, android.content.IntentFilter@c009614f):
    Context.registerReceiver(null, android.content.IntentFilter@c009614f): expected: 1, actual: 0
    Context.registerReceiver(null, android.content.IntentFilter@c009614f): expected: 1, actual: 0

expectedactual 号码开始根据调用次数而变化。