Un marco de burla elimina la redundancia y la repetición de una prueba de burla.
Sabe crear el objeto Mock porque usted se lo dice, por supuesto (a menos que desee decir algo más con esa pregunta).
La forma "estándar" de crear un objeto simulado es usar/abusar de la clase java.lang.reflect.Proxy para crear una implementación en tiempo de ejecución de la interfaz. Esto se hace en tiempo de ejecución. Proxy tiene una limitación en cuanto a que no puede proxy clases concretas. Para lograr la burla de clases concretas se requiere la creación dinámica de códigos de bytes que crea subclases que anulan la implementación real de los métodos públicos, básicamente con lo que se haría con un Proxy (registrar los parámetros del método y devolver un valor predeterminado). Esto tiene una limitación en cuanto a que no puede subclasificar las clases finales. Para eso, tiene soluciones como JDave, que (creo que no confirmé esto) se ensucian con el cargador de clases para eliminar la designación final en la clase antes de cargarla, por lo que la clase no es definitiva en tiempo de ejecución en la medida de lo posible como se trata de la JVM.
El marco de Mocking consiste básicamente en capturar los parámetros y verificarlos contra expectativas predeterminadas, y luego devolver un valor predeterminado preconfigurado o razonable. No se comporta de una manera particular, que es el punto. Se está verificando que el código de llamada llama al método con el parámetro correcto, y tal vez cómo reacciona a un valor de retorno específico o excepciones lanzadas. Cualquier efecto secundario o logro real de la llamada en el objeto real no ocurre.
Aquí hay un ejemplo real de un proyecto, usando JMock con JUnit4. He agregado comentarios para explicar lo que está pasando.
@RunWith(JMock.class) //The JMock Runner automatically checks that the expectations of the mock were actually run at the end of the test so that you don't have to do it with a line of code in every test.
public class SecuredPresentationMapTest {
private Mockery context = new JUnit4Mockery(); //A Mockery holds the state about all of the Mocks. The JUnit4Mockery ensures that a failed mock throws the same Error as any other JUnit failure.
@Test
public void testBasicMap() {
final IPermissionsLookup lookup = context.mock(IPermissionsLookup.class); //Creating a mock for the interface IPermissionsLookup.
context.checking(new Expectations(){{ //JMock uses some innovative but weird double brace initialization as its standard idom.
oneOf(lookup).canRead(SecuredEntity.ACCOUNTING_CONTRACT);
//expect exactly one call to the IPermissionsLookup.canRead method with the the enum of ACCOUNTING_CONTRACT as the value. Failure to call the method at all causes the test to fail.
will(returnValue(true)); //when the previous method is called correctly, return true;
}});
Map<String, Component> map = new SecuredPresentationMap(lookup, SecuredEntity.ACCOUNTING_CONTRACT);
//This creates the real object under test, but passes a mock lookup rather than the real implementation.
JLabel value = new JLabel();
map.put("", value);
assertThat(((JLabel) map.get("")), is(value)); //This ensures that the Map returns the value placed, which it should based on the fact that the mock returned true to the security check.
}
}
Si se pasó por alto el simulacro, la prueba habría fallado. Si el mapa no devuelve el valor colocado en él, la prueba falla (que es JUnit estándar).
Lo que se está probando aquí y en otra prueba opuesta es que dependiendo de lo que la interfaz IPermissionsLookup dice acerca de la seguridad del mapa cambia su comportamiento en lo que se devuelve. Este es el buen caso base. La otra prueba, el simulacro devuelve falso y se espera algo más del mapa. Usar el simulacro asegura que el mapa se basa en el método IPermissionsLookup para determinar la postura de seguridad y lo que se devuelve.
Puede que no haya deseado las respuestas de "mejor estructura", pero eso es lo que obtendrá ... – skaffman
Vea también http://stackoverflow.com/questions/2277039/how-do-mock-frameworks-work , aunque las respuestas allí son muy técnicas. –