mock example dzone java junit mocking easymock mockito

java - example - JUnit burlándose con Mockito, EasyMock, etc.



mockito stub (6)

Estoy tratando de burlarme 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 alguna manera de burlarse de los métodos de la variable "a"? Me gustaría que DoSomethingElse no haga nada durante las pruebas. Actualmente estoy usando Mockito, pero estoy abierto a cualquier marco de burla.

Gracias


Con algunas refactorizaciones 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 puedes usar EasyMock Class Extensions para EasyMock 2.5 o anterior, y aparentemente está incluido en 3.0. Consulte esta parte de la página anterior para obtener información sobre lo que está tratando de hacer. Dicho esto, no he intentado hacerlo personalmente, así que no sé qué tan bien funcionará.


No es posible burlarse de la referencia "a" cuando se declara como una variable local, como en su caso. Podría considerar inyectar la dependencia a SomeObject, por ejemplo, como un parámetro del método doSomething. De esta forma, puedes inyectar un simulacro de SomeObject en tu prueba.

Uno de los beneficios de la inyección de dependencia es una mayor capacidad de prueba .


Si desea una nueva instancia en cada llamada, le sugiero refactorizar de la siguiente manera:

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

A continuación, puede crear una clase de prueba que amplíe ClassToTest, anulando el método getInstance (), con uno que proporcione un objeto simulado.

Por supuesto, esto solo es viable si estás de acuerdo con exponer el método getInstance (), por lo que no lo recomiendo si la clase es parte de una API pública. Si este es el caso, considere proporcionar una clase de fábrica con inyección de dependencia.


class ClassToTest { private SomethingElseInterface somethingElseDoer ; public ClassToTest(SomethingElseInterface somethingElseDoer) { this.somethingElseDoer = somethingElseDoer; } public doSomething () { somethingElseDoer.doSomethingElse(); } }

Y donde lo usas:

SomethingElseInterface somethingElseDoer = ...; // in a test, this is where you mock it ClassToTest foo = new ClassToTest(somethingElseDoer); // inject through constructor foo.doSomething();


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

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

No es necesario refactorizar el código bajo prueba para usar un wrapper, DI, etc; simplemente simula lo que necesites para burlarte.