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
expected
和 actual
号码开始根据调用次数而变化。
我的 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
expected
和 actual
号码开始根据调用次数而变化。