2008-10-10 10 views
6

Decir que tengo clase A con¿Cómo hacer para burlarse de una clase con los métodos finales?

class A { 
    final String foo() { 
    // .. computing result, contacting database, whatever .. 
    return "some computed value"; 
    } 
    // ... and a bazillion other methods, some of them final. 
} 

Ahora tengo clase B con

class B { 
    String methodIWantToTest(A a) { 
     String output = a.foo(); 
     // ... whatever this method does, e.g.: 
     output += "_suffix"; 
     return output; 
    } 
} 

¿Cómo hago para unidad de pruebas de este método? La razón por la cual foo() es final es porque no queremos que nuestras clases que extienden A cambien su funcionalidad. Pero al mismo tiempo, para probar verdaderamente el método, no quiero que se extienda y ejecute el método real A.foo().

¿Hay alguna manera de, por ejemplo, eliminar la palabra clave final y agregar una anotación a lo largo de las líneas de @finalUnlessTest? ¿Qué recomendarías? Refactorizar A a una interfaz sería muy, muy difícil, ya que es una de nuestras clases centrales y desafortunadamente es bastante extremadamente acoplado.

Edit # 1 Lo sentimos, se olvidó de mencionar, estamos hablando de Java. No estamos utilizando un marco burlón hasta el momento.

Respuesta Bien, entonces: wow. JMockit es simplemente increíble y, en mi opinión, es la aplicación clave para probar el código heredado. Increíblemente útil, especialmente en mi caso. ¡Muchas gracias! Es, básicamente, deberías hacer algo como lo siguiente para mi pseudo-ejemplo:

class AMock { 
    final String foo() { 
    return "myTestValue"; 
    } 
} 
class Test extends TestCase { 
    A mockedA; 
    B b; 
    protected void setUp() { 
     Mockit.redefineMethods(A.class, AMock.class); // this "pipes" all mocked methods from A to AMock 
     mockedA = new A(); // NOT new AMock()!!! 
     b = new B(); 
    } 
    public void testB() { 
     assertEquals("myTestValue",mockedA.foo()); 
     assertEquals("myTestValue_suffix",b.methodIWantToTest(mockedA)); 
    } 
} 

Es este maldito frío o qué?

+0

A juzgar por las mayúsculas, debe ser Java. – jop

+0

¿puede decirnos qué idioma usa (parece java)? algunas respuestas pueden ser dependientes del idioma, también díganos qué marco de burla usted usa – Jean

Respuesta

6

Puede probar la biblioteca de burlas JMockit.

+0

parece interesante, lo comprobaré, gracias . – Epaga

0

Quitaría el "final" y simplemente pondré un comentario "¡No anule este método!". Si no puedes confiar en que tus compañeros de trabajo no sigan instrucciones simples, de todas maneras es imposible.

+0

... excepto que no solo estamos hablando de compañeros de trabajo, ya que los clientes pueden usar nuestra API ... – Epaga

0

El siguiente código también le permitirá hacerlo. No estoy diciendo que esto sea una buena práctica, pero es un uso interesante (¿abuso?) De clases anónimas.

public class Jobber { 

    public final String foo() { 
     return fooFactory() ; 
    } 

    String fooFactory() { 
     return "jobber" ; 
    } 


    public static void main(String[] args) { 

     Jobber jobber = new Jobber() { String fooFactory() { return "prefix " + super.fooFactory() ;} } ; 

     System.out.println(jobber.foo()); 
    } 
} 
+0

mmmn. parece duro marcar esto sin dar una razón. Supongo que no debería tomar estas cosas personalmente. Hay un interesante artículo que analiza esta estrategia de probar objetos aquí ... http://www.ibm.com/developerworks/library/j-mocktest.html –

Cuestiones relacionadas