2012-09-14 19 views
5

Estoy intentando escribir una prueba unitaria que necesita confirmar si se llama o no a un método. Estoy usando JUnit, Mockito y PowerMock.Cómo verificar si se llama al método en el sistema bajo prueba (no es un simulacro)

 
public class Invoice 
{ 

    protected void createInvoice() 
    { 
    // random stuff here 
    markInvoiceAsBilled("57"); 
    } 

    protected void markInvoiceAsBilled(String code) 
    { 
    // marked as billed 
    } 
} 

Por lo tanto, aquí mi sistema bajo prueba es Invoice. Estoy corriendo esta prueba:

 
    public class InvoiceTest 
    { 
    @Test 
    public void testInvoiceMarkedAsBilled() 
    { 
     Invoice sut = new Invoice(); 
     Invoice sutSpy = spy(sut); 

     sut.createInvoice(); 

     // I want to verify that markInvoiceAsBilled() was called 
    } 
    } 

Este ejemplo es sólo un ejemplo de lo que el código real se parece ....

Mi problema es que Mockito dice que sólo se puede verificar si se llama un método en un objeto burlado ... pero no quiero burlarme de este objeto, ya que es mi objeto bajo prueba. Sé que usted puede espiar en el objeto que está probando, por lo que aquí es lo que he intentado:

 

    verify(sutSpy).markInvoiceAsBilled("57"); 

es lo que estoy tratando de hacer no es posible? ¿O simplemente lo estoy haciendo mal?

Gracias a todos :)

Respuesta

5

no estoy seguro si lo que está tratando de hacer es la mejor manera de hacer las cosas.

no me ocupo de verificar que Invoice.createInvoice() llama a un método interno, privado markInvoiceAsBilled() - en lugar de prueba que llamar createInvoice() cambia el estado del objeto de la factura en la forma esperada - es decir, que es ahora statusBILLED o algo similar .

En otras palabras - NO probar qué métodos son llamados por createInvoice() - prueba que después de llamar a este método, el estado del objeto es lo que esperas.

0

Acepto la respuesta de matt-b. Dicho esto, dependiendo del caso de uso y la complejidad del método, puede rediseñar su unidad para que pueda ser probada.

Digamos, por ejemplo, que su objeto se vuelve mucho más complicado, p.

public A { 
    public a() { 
    b(); 
    c(); 
    } 

    public b() { /** hairy code, many branches to test */ } 
    public c() { /** hairy code, many branches to test */ } 
} 

Cubriendo B y C con pruebas pruebas es sencillo, pero que cubre un aspirante a parecer una molestia ya que dependerá de los métodos by c.

considerar en cambio este diseño

public A { 
    private final Dep mDep; 

    public a() { 
    mDep.b(); 
    mDep.c(); 
    } 

    public b() { 
    mDep.b(); 
    } 

    public c() { 
    mDep.c(); 
    } 

    // dependency abstraction we create to help test 
    static class Dep { 
    public b() { /** hairy code, many branches to test */ } 
    public c() { /** hairy code, many branches to test */ } 
    } 
} 

Ahora, probando A.a, A.b y A.c simplemente se requiere para verificar su mDep se llama (entre cualquier otra cosa que el método lo hace). Por separado, prueba los métodos A.Dep.b y A.Dep.c.

Cuestiones relacionadas