Как переопределить время выполнения метода экземпляра / конкретного класса? (например, отражение, cglib) - PullRequest
0 голосов
/ 29 октября 2011

То, что я хочу сделать, - это метод, который может

  • генерирует экземпляр класса X (переменная класса передается в arg) и
  • переопределить некоторые из его методов

В частности, родительский класс X, который я хочу переопределить, содержит

  • Не содержит конструктор по умолчанию (например, все конструкторы с аргументами)
  • Конструкторы, вызывающие не приватный метод в том же классе

Первоначально я думал, что довольно просто использовать отражение или что-то подобное, Тогда я обнаружил, что есть ограничение на выполнение моего требования.

Я думаю, что это достижимо, так как Mockito может выполнять все виды выполнения метода инъекций.
Пожалуйста, кто-нибудь дать совет, спасибо.
Изображение псевдокода I выглядит следующим образом:

createAndOverride(Class X) {
    X newObj = X.newInstance(args) {
        @override
        methodOfX(args2) {
            ...
        }
    }
    return newObj;
}
  • Исходный сценарий проблемы

Я был предназначен для тестирования класса, в котором есть несколько методов, вызывающих X1.get (), X2.get (), X3.get ()
В некоторых тестовых случаях мне нужно сделать Xn.get (), чтобы вернуть что-то, что я могу контролировать для теста (например, ноль)
Из-за нижеприведенного ограничения:

  • Но из-за ограничения фиктивного инструмента JMock 1.0 (у меня нет контроля :(), поэтому я не могу просто насмехаться над Xn.get (), возвращая «someSpecifiedObjects»
  • Xn не имеет нулевых конструкторов и конструкторов, вызывающих не приватный член

Мой обходной путь - самодельный класс Xn, и я передаю его в тестовый набор, чтобы ожидать Cn.get ()
Пример кода:

ClassToTest.SomeMethod(new X1() {
    @override
    get() {
        return someSpecifiedObjects;
    }
});

И такие вещи распространяются на Тестовый набор.
Поэтому, чтобы уменьшить количество дублирующегося кода, я хотел бы создать метод для генерации экземпляра Xn с указанным переопределенным методом для тестирования. например

X1 x1 = createAndOverride(X1);

Тогда проблема этого поста наступает

Ответы [ 2 ]

1 голос
/ 29 октября 2011

вы ищете что-то вроде javassist ? Вы можете кодировать инструмент и внедрять свои методы во время выполнения. Я лично стараюсь максимально избегать манипулирования байтовым кодом. Разве вы не можете иметь эти переопределения в своей кодовой базе, а не делать на лету? Может быть что-то вроде обертки?

0 голосов
/ 30 октября 2011

Итак, я думаю, что вам нужна функциональность, аналогичная C * Reflection.Emit:

Хотя я сам этого не сделал, яЯ думаю, что вы должны быть в состоянии использовать отражение / излучение и создание динамического типа для достижения того, что вы ищете.Однако я все же хотел бы отметить, что если вы пытаетесь протестировать «функциональность», которая не относится к пути кода функции, которую вы тестируете, то, вероятно, вам вообще не следует ее тестировать.Например:

SomeObjectInterface get()
{
    if(_someObjectStateIsSet)
    {
        // Return a concrete implementation A
        return new ConcreteImplA();
    }
    else
    {
        // Return a concrete implementation B
        return new ConcreteImplB();
    }
}

В этом случае get не имеет пути к коду, который вернул бы null, поэтому вам не нужно проверять на null.Я не уверен, что правильно понял ваш вопрос на 100%, особенно, почему вы тестируете null, но примите во внимание приведенный выше совет и посмотрите, что работает для вас.

...