¿Causa de un comportamiento inesperado usando el mecanismo de excepción esperado de JUnit 4?

Estoy tratando de probar que un método particular arroja una excepción esperada de un método. Según la documentación de JUnit4 y esta respuesta , escribí la prueba como:

@Test(expected=CannotUndoException.class) public void testUndoThrowsCannotUndoException() { // code to initialise 'command' command.undo(); } 

Sin embargo, este código no pasa la prueba de JUnit, reportando la excepción lanzada (y esperada) como un error.

El método que estoy probando solo tiene esto en el cuerpo:

 public void undo() { throw new CannotUndoException(); } 

Además, la siguiente prueba pasa:

 public void testUndoThrowsCannotUndoException() { // code to initialise 'command' try { command.undo(); fail(); } catch (CannotUndoException cue){ } } 

Lo que significa que la excepción esperada es realmente lanzada.

En realidad, estoy planeando cambiar el método para hacer algo, en lugar de solo lanzar la excepción, pero tengo curiosidad por saber cuál fue la causa del problema, para que no vuelva a suceder en el futuro.

Se han realizado los siguientes controles:

  • la CannotUndoException importada en el caso de prueba es la correcta
  • la versión 4 de JUnit es la única en mi classpath
  • un espacio de trabajo limpio y comstackdo de Eclipse no cambió el resultado

Estoy usando JUnit 4.1, y en la misma prueba estoy usando Mockito.

¿Qué podría estar causando el fallo erróneo?

He encontrado el problema.

El TestRunner que estaba usando era el correcto (JUnit 4), sin embargo, declaré mi clase de prueba como:

 public class CommandTest extends TestCase 

Lo que supongo que está causando que el corredor de pruebas lo trate como una prueba JUnit 3. extends TestCase y recibí los resultados esperados.

Tu código de prueba me parece bien.

Verifique que esté ejecutando un junt 4 testrunner, no un junit 3.8 testrunner; este podría ser el culpable aquí (intente iniciar desde la línea de comandos o simplemente inspeccione visualmente la línea de comandos cuando ejecute su prueba). La ruta de clase de su corredor de prueba puede no ser la misma que la ruta de clase de su proyecto

Este es particularmente el caso dentro de IDE. Alternativamente, también puede intentar presionar Junit 4.4 y ver si eso resuelve su problema. (Junit 4.5 puede causar otros problemas).

Tuve un problema similar y lo arreglé agregando la anotación

 @RunWith(JUnit4ClassRunner.class) 

Lo que le dice al probador de unidades que lo ejecute con la versión 4er de Junit

Curioso.

Escribí tres clases:

Un UndoCommand:

 public class UndoCommand { public void undo() { throw new CannotUndoException(); } } 

A Cannot UndoException:

 // Note: extends the unchecked superclass RuntimeException public class CannotUndoException extends RuntimeException { public CannotUndoException() { super(); } public CannotUndoException(String message) { super(message); } public CannotUndoException(String message, Throwable cause) { super(message, cause); } public CannotUndoException(Throwable cause) { super(cause); } } 

Y una clase de prueba JUnit 4.4:

 import org.junit.Test; public class UndoCommandTest { @Test(expected=CannotUndoException.class) public void testUndo() { UndoCommand command = new UndoCommand(); command.undo(); } } 

Funciona perfectamente – todas las pruebas pasan, resultado “verde”.

Si elimino (esperado = …) de la anotación, la prueba falla, como se esperaba.

Estoy usando Sun JDK 6, JUnit 4.4 e IntelliJ 7.0.5.

¿En qué se diferencia el tuyo?