Скажите, у меня есть класс А с
class A {
final String foo() {
// .. computing result, contacting database, whatever ..
return "some computed value";
}
// ... and a bazillion other methods, some of them final.
}
Теперь у меня есть класс B с
class B {
String methodIWantToTest(A a) {
String output = a.foo();
// ... whatever this method does, e.g.:
output += "_suffix";
return output;
}
}
Как мне провести модульное тестирование этого метода? Причина, по которой foo()
является окончательной, заключается в том, что мы не хотим, чтобы наши классы, расширяющие A, изменили свою функциональность. Но в то же время для истинного модульного тестирования метода я не хочу, чтобы он протянул руку и запустил реальный метод A.foo()
.
Есть ли способ, скажем, удалить ключевое слово final и добавить аннотацию по линии @finalUnlessTest
? Чтобы вы посоветовали? Реорганизовать A в интерфейс было бы очень и очень сложно, учитывая, что это один из наших центральных классов и, к сожалению, довольно чрезвычайно связан.
Редактировать # 1 Извините, забыл упомянуть, мы говорим на Java. Мы еще не используем фальшивый фреймворк.
Ответ ОК, итак: вау. JMockit просто невероятно и, на мой взгляд, является убийственным приложением для тестирования устаревшего кода. Невероятно полезно, особенно в моем случае. Спасибо! По сути, вы бы сделали что-то вроде следующего для моего псевдо-примера:
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));
}
}
Это чертовски круто или как?