Pergunta

Diga que tenho classe A com

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

Agora eu tenho classe B com

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

Como eu iria testar esse método? A razão foo() é final é porque não queremos nossas classes que estendam A para alterar sua funcionalidade. Mas, ao mesmo tempo, para verdadeiramente o teste de unidade do método, não quero que ele estejam alcança e execute o real A.foo() método.

Existe uma maneira de, digamos, remover a palavra -chave final e adicionar uma anotação ao longo das linhas de @finalUnlessTest? O que você recomendaria? Refatorar A a uma interface seria muito, muito difícil, visto como é uma de nossas classes centrais e infelizmente bonito extremamente acoplado.

Editar #1 Desculpe, esqueci de mencionar, estamos falando de Java. Ainda não estamos usando uma estrutura de zombaria.

Responda OK, então: uau. Jmockit é simplesmente incrível e está aos meus olhos o aplicativo assassino para testar o código legado. Inacreditavelmente útil, especialmente no meu caso. Muito obrigado! Você basicamente faria algo como o seguinte para o meu exemplo de PSUDO:

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));
   }
}

Isso é legal ou o quê?

Foi útil?

Solução

Você pode tentar o Jmockit Biblioteca zombeteira.

Outras dicas

Eu removeria o "final" e apenas colocava um comentário "Não substitua esse método !!". Se você não pode confiar nos colegas de trabalho para não seguir instruções simples, é inútil de qualquer maneira.

O código a seguir também permitirá que você o faça. Não estou dizendo que isso é uma boa prática, mas é um uso interessante (abuso?) De aulas 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() );
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top