Как насмехаться над классом с помощью финальных методов? - PullRequest
6 голосов
/ 10 октября 2008

Скажите, у меня есть класс А с

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

Это чертовски круто или как?

Ответы [ 3 ]

6 голосов
/ 10 октября 2008

Вы можете попробовать макетную библиотеку JMockit .

0 голосов
/ 13 октября 2008

Следующий код также позволит вам сделать это. Я не говорю, что это хорошая практика, но это интересное использование (злоупотребление?) Анонимных классов.

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 голосов
/ 10 октября 2008

Я бы удалил «final» и просто добавил комментарий «Не переопределяйте этот метод !!». Если вы не можете доверить коллегам, что они не следуют простым инструкциям, это все равно безнадежно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...