尽管期望方法声明,EasyMock“意外的方法调用”

时间:2015-08-12 13:16:46

标签: java android unit-testing intentfilter easymock

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

在这行代码中测试失败:

<!--Folowing element will be deleted-->
<span> Hello world</span>
<!-- the next one should be kept -->
<span> keep me !</span>

测试:

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
}

4 个答案:

答案 0 :(得分:4)

当你写这样的东西时,

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();

通过这个,easymock理解当IntentFilter的任何对象作为参数传递时,它必须模拟对期望方法的所有调用

希望这有帮助! 祝你好运!

答案 1 :(得分:2)

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

我不确定在IntentFilter上是否编写了工作等号。查看文档,可能并非如此。所以这就是没有匹配的原因。

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

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

答案 2 :(得分:1)

对于遇到此问题的人,请注意在测试中调用源代码方法的次数应等于设置 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 数字开始根据呼叫次数而变化。

答案 3 :(得分:0)

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

当记录方法时匹配器与原始值混合时,通常会发生此异常:

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

对于每一个参数,你不能使用匹配器或匹配器:

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

foo(5, 6);  // also right