Предположим, у меня есть интерфейс с множеством методов, которые я хочу смоделировать для теста, и предположим, что мне не нужно ничего делать, мне просто нужен тестируемый объект, чтобы иметь экземпляр этого. Например, я хочу провести некоторое тестирование / тестирование производительности для определенного фрагмента кода и не хочу, чтобы методы этого интерфейса вносили свой вклад.
Существует множество инструментов, позволяющих сделать это легко, например,
Interface mock = Mockito.mock(Interface.class);
ObjectUnderTest obj = ...
obj.setItem(mock);
или что угодно.
Однако все они идут с некоторыми накладными расходами во время выполнения, которых я бы предпочел избежать:
- Mockito записывает все вызовы, сохраняя аргументы для проверки позже
- JMock и другие (я полагаю) требуют, чтобы вы определили, что они собираются делать (не такая уж большая проблема), и затем выполнение проходит через прокси различных типов для фактического вызова метода.
- Старый добрый java.lang.reflect.Proxy и его друзья проходят, по крайней мере, еще несколько вызовов методов в стеке, прежде чем добираться до вызываемого метода, часто рефлексивно.
(Я желаю, чтобы меня исправили на любом из деталей этих примеров, но я верю, что принцип верен.)
То, к чему я стремлюсь, - это «настоящая» неоперируемая реализация интерфейса, такая, которую я мог бы написать вручную, когда все возвращает null
, false
или 0
. Но это не помогает, если я чувствую себя ленивым, и интерфейс имеет множество методов. Итак, как я могу сгенерировать и создать такую реализацию произвольного интерфейса без возможности выполнения во время выполнения?
Доступны такие инструменты, как Powermock, CGLib, которые используют генерацию байт-кода, но только как часть более широкого контекста насмешек / прокси, и я пока не выяснил, что выбрать из внутренних компонентов.
Хорошо, так что пример может быть немного надуманным, и я сомневаюсь, что прокси будет иметь слишком существенное влияние на время, но мне любопытно, как создать такой класс. Легко ли в CGLib, ASM?
РЕДАКТИРОВАТЬ: Да, это преждевременная оптимизация, и нет никакой необходимости делать это. После того, как я написал этот вопрос, я думаю, что последнее предложение не совсем убедило меня в том, что меня больше интересует, как это сделать в принципе, и простых способов динамической генерации классов, чем фактического варианта использования, который я дал. Возможно, плохо сформулировано с самого начала.