Pregunta

Estoy tratando de burlarse de un método de un objeto dentro de la clase que estoy probando.

Por ejemplo

class ClassToTest {
   public doSomething () {
       SomeObject a = new SomeObject ();
       a.doSomethingElse ();
   }
}

¿Hay una manera de burlarse de los métodos de la variable "a"? Me gustaría doSomethingElse no hacer nada durante las pruebas. Actualmente estoy usando Mockito, pero estoy abierto a cualquier marco de burla.

Gracias

¿Fue útil?

Solución

Sí, hay una manera, como se muestra en la siguiente JMockit prueba:

public void testDoSomething(final SomeObject mock)
{
    new ClassToTest().doSomething();

    new Verifications() {{ mock.doSomethingElse(); }};
}

No hay necesidad de perfeccionar por código bajo prueba a utilizar un envoltorio, DI, etc; simplemente se burlan de lo que tenga que ser burlado.

Otros consejos

No es posible burlarse de la referencia "a" cuando se declara como una variable local, como en su caso. Usted podría considerar la inyección de la dependencia a SomeObject, por ejemplo, como un parámetro de método doSomething. De esta manera, se puede inyectar un simulacro de SomeObject en su prueba en su lugar.

Uno de los beneficios de la inyección de dependencias href="http://blog.wekeroad.com/cool-kids/using-dependency-injection-and-mocking-for-testability/" se incrementa la capacidad de prueba .

Con un poco de refactorización es posible, por supuesto:

class SomeObject {
    public void doSomethingElse()
    {

    }
}

class ClassToTest
{
    private final SomeObject someObject;

    public void doSomething()
    {
        someObject.doSomethingElse();
    }

    public ClassToTest(SomeObject someObject)
    {
        this.someObject = someObject;
    }
}

class Test {
    @Test
    public void testDoSomething()
    {
        SomeObject someObject = Mockito.mock(SomeObject.class);
        new ClassToTest(someObject).doSomething();
        Mockito.verify(someObject, Mockito.atLeastOnce()).doSomethingElse();
    }
}

Creo que se puede utilizar Clase Extensiones EasyMock para EasyMock 2.5 o anterior, y al parecer se incluye en 3.0. Ver esta parte de la página anterior para obtener información sobre lo que está tratando de hacer. Dicho esto, no he probado personalmente para hacer eso, así que no sé lo bien que va a funcionar.

Si desea una nueva instancia en cada llamada, sugeriría refactorización de la siguiente manera:

class ClassToTest {
   public doSomething () {
      SomeObject a = getInstance();
      a.doSomethingElse ();
   }
   protected SomeObject getInstance() {
      return new SomeObject();
   }
}

A continuación, se puede crear un testclass extiende ClassToTest, reemplazando el método getInstance (), con un suministro de un objeto simulado.

Esto es, por supuesto, sólo es viable si estás bien con la exposición del método getInstance (), así que no lo recomiendo si la clase es parte de una API pública. Si este es el caso, considere el suministro de una clase de fábrica mediante la inyección de dependencias.

class ClassToTest {
    private SomethingElseInterface somethingElseDoer ;

    public ClassToTest(SomethingElseInterface somethingElseDoer) {
        this.somethingElseDoer = somethingElseDoer;
    }

    public doSomething () {
        somethingElseDoer.doSomethingElse();
    }
}

Y donde vaya a utilizarlo:

SomethingElseInterface somethingElseDoer = ...; // in a test, this is where you mock it
ClassToTest foo = new ClassToTest(somethingElseDoer); // inject through constructor
foo.doSomething();
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top