PowerMockito:模拟上的NotAMockException

编程入门 行业动态 更新时间:2024-10-24 14:24:15
本文介绍了PowerMockito:模拟上的NotAMockException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

有点复杂的设置。 Robolectric,PowerMockito基于规则的配置。

Bit of a complicated setup. Robolectric, PowerMockito rule-based config.

@RunWith(RobolectricGradleTestRunner.class) @Config(constants = BuildConfig.class, sdk = 21) @PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*"}) // Using "PrepareOnlyThis" prevents powermock from trying to instrument the whole hierarchy, // part of which we've ignored (android.os.* in this case) @PrepareOnlyThisForTest({ServiceCallbackBase.class}) // this class extends Handler, // so we need PrepareOnlyThis. It also has some final methods we need to verify() public class ServiceBaseTests { private class Foo { // nothing } @Rule public PowerMockRule rule = new PowerMockRule(); private ServiceCallbackBase<Object, Foo> setupCallback( boolean hasValidContext, boolean allContextsCanceled ) { ServiceCallbackBase<Object, Foo> callback = PowerMockito.mock( ServiceCallbackBase.class ); // EDIT: I have converted these to PowerMockito.doReturn()s to no avail. PowerMockito.when( callback.hasValidContext() ).thenReturn( hasValidContext ); PowerMockito.when( callback.allContextsAreCanceled( any( Message.class ) ) ).thenReturn( allContextsCanceled ); PowerMockito.doNothing().when( callback ).preSendMessage( any( Message.class ) ); return callback; }

应该很常规。但是,每当我尝试在这些回调模拟实例之一上调用 verify 时,例如:

Should be pretty routine. But whenever I try to call verify on one of these "callback" mock instances, for instance:

private void test_notifyCallback( boolean isFromCache ) { ServiceCallbackBase<Object, Foo> callback = setupCallback( true, false ); uut.addHandler( TestEnum.FOO, callback ); uut.addHandler( TestEnum.BAR, PowerMockito.mock( ServiceCallbackBase.class ) ); uut.addHandler( TestEnum.BAZ, PowerMockito.mock( ServiceCallbackBase.class ) ); Response<Foo> foo = new Response<>( new Foo(), new ResponseStatus( 0, "Error" ) ); uut.handleCallBack( TestEnum.FOO, foo, isFromCache ); ArgumentCaptor<Message> captor = ArgumentCaptor.forClass( Message.class ); // this line throws the error. verify( callback ).preSendMessage( captor.capture() ); assertThat( captor.getValue().what ).isEqualTo( TestEnum.FOO.ordinal() ); assertThat( captor.getValue().obj ).isEqualTo( foo ); assertThat( captor.getValue().arg1 ).isEqualTo( isFromCache ? 1 : 0 ); }

我收到这样的错误:

org.mockito.exceptions.misusing.NotAMockException: Argument passed to verify() is of type ServiceCallbackBase$$EnhancerByMockitoWithCGLIB$$9acf906b and is not a mock! Make sure you place the parenthesis correctly! See the examples of correct verifications: verify(mock).someMethod(); verify(mock, times(10)).someMethod(); verify(mock, atLeastOnce()).someMethod();

mockito显然很明显地增强了,而PowerMock没有verify()代替 Mockito.verify() ...使用的方法是什么?

It's clearly and obviously been "enhanced" by mockito, and PowerMock doesn't have a verify() method to use instead of Mockito.verify()... what gives?

EDIT :从某种程度上来说,这更加令人困惑。

EDIT: this is in some ways more and in some ways less confusing.

我正在构建另一个测试类来测试ServiceCallbackBase本身。如果我从该类中删除测试,则这些测试通过。不同类别中的以下代码片段导致上述测试失败。

I'm in the process of building another test class to test ServiceCallbackBase itself. If I remove the tests from that class, these tests pass. The following snippet in a different class causes the tests above to fail.

@RunWith(RobolectricGradleTestRunner.class) @Config(constants = BuildConfig.class, sdk = 21) public class ServiceCallbackBaseTests { @Test public void test_nothing(){ } private ServiceCallbackBase<Object, String> uutSpy; @Before public void setup(){ uutSpy = mock( ServiceCallbackBase.class ); } }

推荐答案

I无法建立您的示例,但我设法编写了一个导致非常相似问题的小型测试:

I cannot build your example, but I managed to write this minitest that produces a very similar problem:

@RunWith(RobolectricGradleTestRunner.class) @Config(constants = BuildConfig.class, sdk = 21) @PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*"}) @PrepareOnlyThisForTest({ServiceCallbackBase.class, Dummy.class}) public class MainActivityTest { @Rule public PowerMockRule rule = new PowerMockRule(); @Test public void test1() throws Exception { try { //This Mockito.withSettings() thing is important to make the test fail! ServiceCallbackBase callback = PowerMockito.mock( ServiceCallbackBase.class, Mockito.withSettings()); callback.dispatchMessage(null); Mockito.verify(callback).dispatchMessage(null); } catch (Exception e){ e.printStackTrace(); Assert.fail(); } } }

(请注意Mockito.withSettings (),我不知道为什么,但这会使测试失败)

(Note the Mockito.withSettings(), I don't know why but that makes the test to fail)

打印:

org.mockito.exceptions.misusing.NotAMockException: Argument passed to verify() is of type ServiceCallbackBase$$EnhancerByMockitoWithCGLIB$$62776c54 and is not a mock! Make sure you place the parenthesis correctly! ......

好吧,这绝对是一个类加载问题,mockito正在将Powermock加载的ServiceCallbackBase $$ EnhancerByMockitoWithCGLIB $$ etc ..与Robolectric加载的ServiceCallbackBase $$ EnhancerByMockitoWithCGLIB $$ ..(显然,在该比较中返回false)

Well, this absolutely looks as a classloading issue, mockito is comparing ServiceCallbackBase$$EnhancerByMockitoWithCGLIB$$etc.. loaded by Powermock with the same loaded by Robolectric (obviously returning false in that comparision)

然后,我设法使测试工作只需将 org.powermock。* 添加到 @PowerMockIgnore ... 行,这是:

Then, I managed to make the test work simply adding "org.powermock.*"to the line @PowerMockIgnore... this is:

@PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*", "org.powermock.*"})

这个简单的更改使我的测试生效了,我真的希望也是你的。

This simple change made my test to work, and I really hope that make yours too.

更多推荐

PowerMockito:模拟上的NotAMockException

本文发布于:2023-10-31 04:08:03,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1544955.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:PowerMockito   NotAMockException

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!