2012-08-29 61 views
15

Estoy intentando burlarme de un método para ver si manejo una excepción correctamente. Esto es lo más lejos que puedo llegar.Excepción de mockito en doThrow que parece correcta

interfaz:

interface SampleManager { 
    void deleteVariome(String specimenId, String analysisId) throws Exception; 
    // ... 
} 

prueba de unidad:

// ... 
SampleManger sampleManager = mock(SampleManager.class); 

// below is line 753 
doThrow(Exception.class).when(sampleManager).deleteVariome(sample1.getId(), analysisId); 

resultado:

org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here: 
-> at ...server.ArchiveManagerImplUTest.deleteVariomeFails(ArchiveManagerImplUTest.java:753) 

E.g. thenReturn() may be missing. 
Examples of correct stubbing: 
    when(mock.isOk()).thenReturn(true); 
    when(mock.isOk()).thenThrow(exception); 
    doThrow(exception).when(mock).someVoidMethod(); <-- this looks a log like what I did! 

Hints: 

1. missing thenReturn() 

2. you are trying to stub a final method, you naughty developer! <-- I have a lot of other mocks of this interface in this test that work. 

Respuesta

0

que tiene que suministrar una instancia del Exception.class no la propia clase de excepción .

doThrow(new Exception()).when(sampleManager).deleteVariome(sample1.getId(), analysisId); 

EDITAR Bueno @DavidWallace me corrigió, así que ten cuidado (o más bien iluminado) que desde 1.9 sólo puede proporcionar la clase de excepción a lanzar y que va a construir una para usted.

+2

No, desde Mockito 1.9.0 en adelante, se puede suministrar la clase de excepción, y funcionará como esperado.Sin embargo, incluso si el OP está usando una versión anterior de Mockito, no obtendrían el síntoma que están describiendo aquí. Creo que el problema es algo diferente. –

+0

Gracias David. No lo sabía Dejaré mi respuesta aquí para que otros puedan estar al tanto de tu comentario. –

4

Este error generalmente se informa DESPUÉS del lugar donde realmente ocurrió. Si no puedes colgar algo correctamente, Mockito por lo general no puede decir hasta la próxima vez que llames a uno de los métodos de Mockito. Esto podría ser en el mismo método de prueba, un método de prueba posterior en la misma clase o incluso una clase de prueba completamente diferente.

La línea que ha citado se ve bien para mí. Echa un vistazo a las líneas de arriba, donde llamas un método Mockito o verificación. Es muy probable que tenga un when que no tiene asociados thenReturn, then o thenThrow. O puede que tenga un verify al que le falta la llamada al método real. Hay algunas otras posibilidades también.

Si no puede encontrar un error en las líneas ARRIBA del que ha citado, publique un poco más de su código y lo echaré más de cerca.

+1

Además, si utiliza el corredor JUnit 'MockitoJUnitRunner.class', Mockito comprobará que su método de prueba no tenga ningún trozo inacabado. Lo que ayudará a aislar este error al origen del problema. – Brice

+0

a OP: Si quiere asegurarse de que es el problema, es fácil: simplemente ejecute ese método de prueba específico y debería encontrar que funciona bien. O puede poner un reinicio simulado justo antes de su lógica de prueba real, y puede encontrar que la prueba funciona bien. Estos son los síntomas del problema descrito por David Wallace –

+0

Pero el problema PUEDE estar realmente en el mismo método de prueba. Por lo tanto, puede obtener el error ejecutando solo el método de prueba. En ese caso, también, usar 'MockitoJUnitRunner' no te ayudará. –

17

De un problema idéntico al que acabo de encontrar, sospecho que sample es un simulacro, y ha fallado sample.getId() en otro lugar? Eso causó este problema en mi caso, de todos modos.

Por alguna razón, Mockito se molesta si uno de los argumentos que pasa al stub utilizado con doThrow de esta manera es el resultado de un método que también se burló. Tal vez sea una especie de verificación de reentrada para evitar bucles infinitos, no sé.

En cualquier caso, intente reemplazar sample.getId() con un valor constante y eso debería resolver el problema. Podría considerar el uso de una constante declarada en su prueba tanto para el simulacro como para otros usos posteriores. También podría verificar que el método que está probando usó sample.getId() agregando otra llamada al verify.

+0

Me enfrenté al mismo problema ... lo resolví al no pasar un valor constante en lugar de un simulacro. –

+0

gracias hombre! Lo resuelvo pasando en el método 'thenReturn' una variable local en lugar del valor directamente del getter. – Juancho

4

Como se describe en la respuesta de Gijs, esto se debe probablemente a un error en Mockito. Aquí está una prueba completa, que lo reproduce:

interface Sample { String getId(); } 
interface SampleManager { 
    void deleteVariome(String specimenId, String analysisId); 
} 

@Test 
public void probableMockitoBug() { 
    Sample sample1 = mock(Sample.class); 
    when(sample1.getId()).thenReturn("a"); 

    SampleManager manager = mock(SampleManager.class); 
    doThrow(Exception.class).when(manager).deleteVariome(sample1.getId(), "b"); 

    manager.deleteVariome("a", "b"); 
} 

La prueba produce el siguiente resultado:

 
org.mockito.exceptions.misusing.UnfinishedStubbingException: 
Unfinished stubbing detected here: 
-> at org.mockitousage.JavadocExamplesTest.probableMockitoBug(JavadocExamplesTest.java:404) 

E.g. thenReturn() may be missing. 
Examples of correct stubbing: 
    when(mock.isOk()).thenReturn(true); 
    when(mock.isOk()).thenThrow(exception); 
    doThrow(exception).when(mock).someVoidMethod(); 
Hints: 
1. missing thenReturn() 
2. you are trying to stub a final method, you naughty developer! 

    at org.mockito.exceptions.Reporter.unfinishedStubbing(Reporter.java:55) 
    at org.mockito.internal.progress.MockingProgressImpl.validateState(MockingProgressImpl.java:74) 
    at org.mockito.internal.progress.ThreadSafeMockingProgress.validateState(ThreadSafeMockingProgress.java:49) 
    at org.mockito.internal.MockHandler.handle(MockHandler.java:71) 
    at org.mockito.internal.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:36) 
    at org.mockito.internal.creation.MethodInterceptorFilter.intercept(MethodInterceptorFilter.java:48) 
    at org.mockitousage.JavadocExamplesTest$Sample$$EnhancerByMockitoWithCGLIB$$d5ac41.getId() 
    at org.mockitousage.JavadocExamplesTest.probableMockitoBug(JavadocExamplesTest.java:404) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37) 
    at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62) 
+0

Si es así, entonces la solución simple es: 'doThrow (Exception.class) .when (manager) .deleteVariome (" a "," b ");' –

Cuestiones relacionadas