Как насмехаться над классом с помощью финальных методов?

StackOverflow https://stackoverflow.com/questions/190597

Вопрос

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

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 в интерфейс было бы очень и очень сложно, учитывая, что это один из наших центральных классов и, к сожалению, он довольно чрезвычайно связан.

Edit # 1 Извините, забыл упомянуть, мы говорим на Java. Мы пока не используем фальшивый фреймворк.

Ответ . Итак, вау. JMockit просто невероятен и, на мой взгляд, является убийственным приложением для тестирования устаревшего кода. Невероятно полезно, особенно в моем случае. Спасибо! По сути, вы бы сделали что-то вроде следующего для моего примера psuedo:

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

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

Это было полезно?

Решение

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

Другие советы

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

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

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() );
    }
}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top