Mock Retrofit service with Mockito causes ExceptionInInitializerError

匿名 (未验证) 提交于 2019-12-03 01:00:01

问题:

I tried with:

androidTestCompile 'org.mockito:mockito-core:2.0.26-beta' 

...

public interface CustomerService {     @POST("url")     Observable<Session> createSession(@Body Credential credential); } 

...

@RunWith(AndroidJUnit4.class) @LargeTest public class LoginActivityTests {      @Before     public void setUp() {         customerService = Mockito.mock(CustomerService.class);     }      @Test     public void testLoginGoToNextScreen() throws Exception {        doReturn(new Session"token")).when(customerService).createSession(            new Credential("aa", "123", new Device("asd", ":)")));     } 

But it crash always.

java.lang.ExceptionInInitializerError at org.mockito.internal.exceptions.stacktrace.ConditionalStackTraceFilter.<init>(ConditionalStackTraceFilter.java:17) at org.mockito.exceptions.base.MockitoException.filterStackTrace(MockitoException.java:41) at org.mockito.exceptions.base.MockitoException.<init>(MockitoException.java:30) at org.mockito.internal.configuration.plugins.PluginLoader.loadPlugin(PluginLoader.java:35) at org.mockito.internal.configuration.plugins.PluginRegistry.<init>(PluginRegistry.java:12) at org.mockito.internal.configuration.plugins.Plugins.<clinit>(Plugins.java:11) at org.mockito.internal.util.MockUtil.<clinit>(MockUtil.java:23) at org.mockito.internal.MockitoCore.<init>(MockitoCore.java:44) at org.mockito.Mockito.<clinit>(Mockito.java:1101) at com.pickupnow.customer.LoginActivityTests.setUp(LoginActivityTests.java:48) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24) at android.support.test.internal.statement.UiThreadStatement.evaluate(UiThreadStatement.java:55) at android.support.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:257) at org.junit.rules.RunRules.evaluate(RunRules.java:20) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runners.Suite.runChild(Suite.java:128) at org.junit.runners.Suite.runChild(Suite.java:27) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at org.junit.runner.JUnitCore.run(JUnitCore.java:115) at android.support.test.internal.runner.TestExecutor.execute(TestExecutor.java:54) at android.support.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:228) at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:1729) Caused by: java.lang.NullPointerException at org.mockito.internal.configuration.plugins.Plugins.getStackTraceCleanerProvider(Plugins.java:17) at org.mockito.internal.exceptions.stacktrace.StackTraceFilter.<clinit>(StackTraceFilter.java:21) ... 41 more 

Is there another way to do it?

回答1:

I always test like:

when(customerService.createSession(any())).thenReturn(Observable.just(new Session("token"))); 

If you need to specify what parameter must be used, instead of any(), you could write your ArgumentMatcher (http://mockito.googlecode.com/hg-history/1.6/javadoc/org/mockito/ArgumentMatcher.html). I hope this helps.



回答2:

It can be done using MockRestAdapter.

It is simple, just need to create a MockedService that implements the original Service declaration, create an instance and set it to your code service instance:

Before each tests...:

MockOrderService.mock(new Order("fake-data")) 

Example of a mocked service:

public class MockOrderService implements OrderService {      private Order mOrder;      public static void mock(Order order){         mOrder = order;          // Setup MockRestAdapter without delays or posible errors         MockRestAdapter mockRestAdapter = MockRestAdapter.from(ApiManager.REST_ADAPTER);         mockRestAdapter.setDelay(0);         mockRestAdapter.setErrorPercentage(0);         mockRestAdapter.setVariancePercentage(0);          // Create the mocked service and replace it in         MockOrderService mockOrderService = new MockOrderService();         mockOrderService.mOrder = order;          // Replace the service instance with the mocked one         // Then every time that the projec call Order.get will return what we          // had in our MockOrderService.get() code         Order.SERVICE = mockRestAdapter.create(OrderService.class, mockOrderService);     }      // OrderService override     @Override     public Observable<Order> get(@Path("id") String id) {         return Observable.just(mOrder);     }  } 

Order.SERVICE should be the instance that the project uses for requests.

Take a look to this post MakinGIANTS Post.

---EDIT--- If you are trying to unit test your app is easier to mock if you wrap your retrofit service inside some kind of repository, then you can mock the repository functions itself.



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!