2011-09-28 23 views
9

Estoy luchando tratando de enseñarme a mí mismo Mockito.Mockito "cuando" problema

Considere el siguiente método, hasInventory(), que en realidad no debería correr en mi forma de pensar, pero ponerse en marcha para volver verdadera o falsa como jaula de ardilla mi prueba. Clase Almacén es mi "dependencia burlada".

public class Warehouse implements IWarehouse 
{ 
    private Map< String, Integer > inventory; 

    public Warehouse() 
    { 
    this.inventory = new HashMap< String, Integer >(); 
    } 

    public final boolean hasInventory(String itemname, int quantity) 
     throws InventoryDoesNotExistException 
    { 
    if(inventory == null) 
     throw new InventoryDoesNotExistException(); 

    if(!inventory.containsKey(itemname)) 
     return false; 

    int current = (inventory.containsKey(itemname)) ? inventory.get(itemname) : 0; 

    return(current >= quantity); 
    } 
    ... 

En el código de prueba JUnit, la primera cuando() se produce una excepción, ya que, literalmente, interpreta la llamada al método (ejecutarlo) y, inventario siendo nula (véase más arriba), InventoryDoesNotExistException es arrojado. También hay otros métodos en la clase de dependencia burlada, como add() y remove().

@RunWith(MockitoJUnitRunner.class) 
public class OrderInteractionTest 
{ 
    private static final String TALISKER = "Talisker"; 
    private Order systemUnderTest = null; 

    @Mock 
    private Warehouse mockedDependency = null; 

    @Before 
    public void init() 
    { 
    //MockitoAnnotations.initMocks(this); 
    //mockedDependency = mock(Warehouse.class); 
    this.systemUnderTest = new Order(TALISKER, 50); 
    } 

    @Test 
    public void testFillingRemovesInventoryIfInStock() 
    { 
    try 
    { 
     doNothing().doThrow(new RuntimeException()).when(mockedDependency).add(anyString(), anyInt()); 
     doNothing().doThrow(new RuntimeException()).when(mockedDependency).remove(anyString(), anyInt()); 
     when(mockedDependency.hasInventory(anyString(), anyInt())).thenReturn(true); 
     when(mockedDependency.getInventory(anyString())).thenReturn(50); 

como yo lo entiendo, por el cuando() método, te pido Mockito precisamente no llamar hasInventory(), pero sólo para volver cierto lugar cada vez que se llama como pruebo la clase ("systemUnderTest"). ¿Alguien puede ayudarme a superar este punto (o tener algo de sentido en mi cerebro)?

estoy vinculando Mockito-all-1.8.5.jar y JUnit 4.

copiosas gracias a todos los que leen esto.

Russ

Respuesta

10

Mockito no puede burlarse final clases o métodos. Intente eliminar el modificador final del método hasInventory. O mejor aún, no se burle de la clase Warehouse, sino que se burle de la interfaz IWarehouse, cuyos métodos no pueden ser final, y presumiblemente define los utilizados por Order.

En general, es preferible simular interfaces, pero no es obligatorio.

No se puede simular final clases o métodos se menciona brevemente en el Mockito FAQ, es debido a la técnica de generación de clases de tiempo de ejecución utilizada para crear los simulacros.

+0

¡Ja! Sí, ese es el problema. De hecho, leí algo sobre esto hoy temprano, pero no hice la conexión. A imitación de otros tutoriales, comencé a burlarme de IWarehouse y eso estaba funcionando, así que pensé que solo podía simular interfaces (estuve hablando con alguien hace unas semanas que me dijo que podía burlarme de clases simples, así que no lo había intentado). para burlarse de la interfaz, ya que pensé que en muchos escenarios de la vida real, ni siquiera tendría una interfaz). ¡Pero esta es la respuesta correcta! Muchas gracias por esto. –

Cuestiones relacionadas