2012-02-21 18 views
5

Estoy usando Mockito 1.9 con Grails 1.3.7 y tengo un error extraño.Error en Mockito con Grails/Groovy

El siguiente caso de prueba en Java funciona:

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(){ 
     } 
    } 
} 

Esta prueba en maravilloso no funciona:

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(){ 
    } 
} 

Este es el mensaje de error:

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) 

¿Se observó anymone el mismo error?

Respuesta

8

El problema es que Groovy está interceptando su llamada al método antes de que llegue a someVoidMethod. El método que realmente se llama es getMetaClass que no es un método vacío.

Usted puede verificar esto está ocurriendo mediante la sustitución:

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

con:

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

No estoy seguro de que será capaz de conseguir evitar este problema utilizando papel Mockito y maravillosa.

+0

¿Qué debería usar entonces? Tengo el mismo problema y estoy atascado con eso. – Guillaume

+0

Puedes probar [mockito-groovy-support] (https://github.com/cyrusinnovation/mockito-groovy-support). Resolvió el problema getMetaClass() para mí – csab