Как работает & # 8220; статическое отражение & # 8221; работать в Java? (например, в mockito или easymock)

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

Вопрос

Я парень .NET, и я в основном пишу на C #.

Начиная с C # 3.0, мы можем использовать лямбда-выражения и деревья выражений для использования статическое отражение . Например, можно реализовать GetMethodName в следующем фрагменте, чтобы вернуть имя метода, переданного в параметре:

string methodName = GetMethodName( o => o.DoSomething());
Console.WriteLine(methodName); // displays "DoSomething"

Теперь, когда я смотрю на образцы Mockito (или EasyMock) в мире Java, я вижу:

LinkedList mockedList = mock(LinkedList.class);
when(mockedList.get(0)).thenReturn("first");

Как это работает?

Как работает метод when ? Как он интерпретирует mockedList.get (0) как вызов метода get, где 0 передается как параметр , а не как значение?

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

Решение

Пересматривающие библиотеки обычно не работают с деревьями выражений. Они создают тип, который реализует соответствующий интерфейс и отвечает на вызовы методов, записывая их или проверяя и возвращая предварительно запрограммированные ответы. Обычно это делается с помощью прокси-сервера (например, RealProxy в .NET, прокси-сервер в Java) или с динамической генерацией кода.

В случае EasyMock он использует Proxy (для интерфейсов, в любом случае), как вы можете видеть в исходном коде: посмотрите на org.easymock.internal.JavaProxyFactory .

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

Библиотеки макетов Java обычно работают следующим образом:

Когда вы создаете макет, создается фактический прокси (будь то интерфейс или подкласс), экземпляр находится в «режиме записи». Это означает, что любой последующий вызов записывается (имя метода, параметры, ожидаемый результат). Обратите внимание, что прокси в режиме записи на самом деле ничего не делает, кроме записи звонков. Там нет отражения как такового. Нет обнаружения метаданных и т. Д. Конечно, эти библиотеки выполняют некоторые приемы (например, сохраняют вызовы в локальной переменной потока для обработки методов, возвращающих void), но идея остается той же.

Затем, когда «режим воспроизведения» запускается, фиктивный экземпляр просто проверяет ожидания из списка вызовов (метод + параметры и возвращаемые значения).

Я никогда не работал с mockito или easymock, но я не думаю, что вызов делает то, что вы думаете. Он не интерпретирует mockedList.get (0) каким-либо особым образом. Метод get выполняется для объекта mockedList в обычном режиме, и результат этого передается в when .

mockedList.get (0) - это синтаксис для вызова метода, который делает именно это. Что этот метод делает, не совсем понятно. Тип времени выполнения mockedList будет подклассом LinkedList , возвращаемого методом mock , который может быть реализован так, как сочтет нужным инфраструктура mocking.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top