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

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

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().

Есть ли способ, скажем, удалить последнее ключевое слово и добавить аннотацию в соответствии со строками @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));
   }
}

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

Судя по заглавным буквам, это должна быть Java.

jop 10.10.2008 13:14

Можете ли вы сказать нам, какой язык вы используете (похоже на java)? некоторые ответы могут зависеть от языка, также сообщите нам, какой фреймворк вы используете

Jean 10.10.2008 13:14
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
6
2
1 218
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

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

... за исключением того, что мы говорим не только о коллегах, поскольку клиенты могут использовать наш API ...

Epaga 10.10.2008 15:44
Ответ принят как подходящий

Вы можете попробовать библиотеку имитации 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() );
    }
}

мммн. кажется резким отмечать это без объяснения причин. Думаю, мне не стоит принимать эти вещи на свой счет. Здесь есть интересная статья, в которой обсуждается эта стратегия тестирования объектов ... ibm.com/developerworks/library/j-mocktest.html

David Turner 13.10.2008 16:28

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