Bug in Mockito with Grails/Groovy

匿名 (未验证) 提交于 2019-12-03 02:30:02

问题:

I am using Mockito 1.9 with Grails 1.3.7 and I have a strange bug.

The following test case in java works:

import static org.mockito.Mockito.*;  public class MockitoTests extends TestCase {      @Test     public void testSomeVoidMethod(){         TestClass spy = spy(new TestClass());         doNothing().when(spy).someVoidMethod();     }      public static class TestClass {          public void someVoidMethod(){         }     } } 

This test in groovy does not work:

import static org.mockito.Mockito.*  public class MockitoTests extends TestCase {      public void testSomeVoidMethod() {         def testClassMock = spy(new TestClass())         doNothing().when(testClassMock).someVoidMethod()     }  }  public class TestClass{      public void someVoidMethod(){     } } 

This is the error message:

only void methods can doNothing()! Example of correct use of doNothing():     doNothing().     doThrow(new RuntimeException())     .when(mock).someVoidMethod(); Above means: someVoidMethod() does nothing the 1st time but throws an exception the 2nd time is called org.mockito.exceptions.base.MockitoException:  Only void methods can doNothing()! Example of correct use of doNothing():     doNothing().     doThrow(new RuntimeException())     .when(mock).someVoidMethod(); Above means: someVoidMethod() does nothing the 1st time but throws an exception the 2nd time is called     at org.codehaus.groovy.runtime.callsite.CallSiteArray.createPogoSite(CallSiteArray.java:129)     at org.codehaus.groovy.runtime.callsite.CallSiteArray.createCallSite(CallSiteArray.java:146)     at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:40)     at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)     at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:120) 

Does anymone observed the same error?

回答1:

The problem is Groovy is intercepting your method call before it reaches someVoidMethod. The method actually being called is getMetaClass which is not a void method.

You can verify this is happening by replacing:

doNothing().when(testClassMock).someVoidMethod() 

with:

doReturn(testClassMock.getMetaClass()).when(testClassMock).someVoidMethod() 

I'm not sure you will be able to get around this issue using stock Mockito and Groovy.



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