2011-02-06 12 views
10

que tiene una clase como esta:código de prueba que llama a los métodos nativos

public final class Foo 
{ 
    public native int getBar(); 

    public String toString() 
    { 
     return "Bar: " + getBar(); 
    } 
} 

Tenga en cuenta que GetBar() se implementa con JNI y que la clase es definitiva. Quiero escribir una prueba junit para probar el método toString(). Para esto tengo que burlarme del método getBar() y luego ejecutar el método original toString() para verificar el resultado.

Mi primer pensamiento fue que esto debe ser imposible, pero luego encontré PowerMock que permite probar las clases finales y los métodos nativos de acuerdo con la lista de características. Pero hasta ahora no tuve éxito con eso. Lo mejor que logré fue burlarme de la clase completa, pero luego la prueba probó el método toString() en lugar del real, lo cual no tiene mucho sentido.

Entonces, ¿cómo puedo usar PowerMock para probar este método toString() desde arriba? Prefiero usar PowerMock con Mockito, pero si esto no es posible, no tengo ningún problema con el uso de EasyMock.

Respuesta

8

Lo encontró. La forma en que lo estaba haciendo era correcta. Lo único que echaba de menos era decirle al objeto simulado que llamara al método original cuando se llamaba aString(). Por lo que funciona de esta manera:

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ Foo.class }) 
public class FooTest 
{ 
    @Test 
    public void testToString() throws Exception 
    { 
     Foo foo = mock(Foo.class); 
     when(foo.getBar()).thenReturn(42); 
     when(foo.toString()).thenCallRealMethod(); 
     assertEquals("Bar: 42", foo.toString()); 
    } 
} 
+1

HI ... No puedo añadir el "cuándo()" .. ¿por qué ..? ¿Puede decirme usando Easymock –

1

O utilice Patrón Estrategia:

public final class Foo 
    { 
     public IBarStrategy barStrategy; 

     ...... 
    } 

    interface IBarStrategy{ 
     int getBar(); 
    } 

Cuando prueba de unidad, inyectar una maqueta IBarStrategy ejemplo, entonces se podría probar la clase Foo.

+3

? La inyección de dependencias es algo bueno para la reutilización y modularidad del código, pero si eso no es necesario, ¿por qué debería aumentar la complejidad y aflojar la API de mis clases solo para probar? Pero ese no es el punto aquí. Entonces, digamos que no puedo cambiar el tema de prueba, así que no puedo extraer los métodos nativos en una interfaz. – kayahr

+0

en realidad no está aumentando la complejidad al hacer esto. su complejidad oculta simplemente al NO hacer esto. deberías diseñar para la capacidad de prueba para comenzar con – Will

3

O utilice JMockit con dinámica parcial burlarse:

import org.junit.*; 
import mockit.*; 

public class FooTest 
{ 
    @Test 
    public void testToString() 
    { 
     final Foo foo = new Foo(); 
     new Expectations(foo) {{ foo.getBar(); result = 42; }}; 

     assertEquals("Bar: 42", foo.toString()); 
    } 
} 
Cuestiones relacionadas