В Java, я могу создать экземпляр анонимного подкласса из объекта Class? - PullRequest
2 голосов
/ 20 августа 2009

У меня есть фабричный метод, который создает объекты для использования в модульных тестах. Все эти объекты происходят из одного базового класса:

public static <T extends BaseEntity> T modMake(Class<T> clazz)
{
    try {
        return clazz.newInstance();
    } catch (InstantiationException e) {
        // Should never happen
        throw new AssertionError(e);
    } catch (IllegalAccessException e) {
        // Should never happen
        throw new AssertionError(e);
    }
}

Теперь я хочу переопределить метод получения из этого базового класса, но только для тестов. Обычно я делаю это с анонимным классом, например (Node является одним из подтипов BaseEntity):

public static Node nodMake()
{
    return new Node() {
        @Override
        public long ixGet() { return 1; }
    };
}

Можно ли сделать это в функции, используя аргумент Class?

Ответы [ 2 ]

3 голосов
/ 20 августа 2009

Потеряйте свой фабричный метод и используйте API-интерфейс для насмешки, например EasyMock , для достижения описанного вами поведения.

Ваш код будет выглядеть примерно так:

long returnValue = 12;

Node nodeMock = createMock(Node.class);
expect(nodeMock.ixGet()).andReturn(returnValue);
replay(nodeMock);

//add test code here

verify(nodeMock);

Чтобы ответить на вопрос Ханно о том, как это работает:

Это зависит от того, издеваетесь ли вы над интерфейсом или классом.

Случай интерфейса прост (с точки зрения кода), он использует так называемый динамический прокси, который является частью ядра Java.

В случае класса он выполняет манипулирование байт-кодом, которое @Jonathan упоминает в своем ответе, прямо за красивым API.

Оба вышеупомянутых механизма позволяют перехватывать вызовы методов, и EasyMock просто отвечает в зависимости от настроенных вами ожиданий.

0 голосов
/ 20 августа 2009

Я не думаю, что есть способ сделать это. Вам, вероятно, нужно изучить манипуляторы с байт-кодом, если вам действительно нужно идти по этому пути. Javassist и BCEL - это несколько вариантов.

...