Как издеваться над нативными методами с помощью jMockit - PullRequest
2 голосов
/ 01 декабря 2009

Я пытаюсь использовать jMockit, чтобы заглушить вызов netscape.javascript.JSObject, который, к сожалению, является абстрактным классом с несколькими нативными методами, оба из которых плохо работают с jMockit. Есть ли способ для меня, чтобы заглушить это, либо с помощью jMockit, либо с помощью простого Java (я бы предпочел не вводить новую библиотеку, если это возможно)? Код, который я пытаюсь внедрить в макет, выглядит примерно так (не спрашивайте):

JSObject win = JSObject.getWindow (this);
String someVal = (String) win.call ("foo", new String [] {""});

К сожалению, я не могу изменить рассматриваемый код (еще раз, не спрашивайте), так что единственный способ, которым я могу выполнить какое-либо модульное тестирование, это если я смогу выяснить, как заглушить или иным образом устранить звонки в JSObject. Моя текущая фиктивная реализация возвращает новый экземпляр самого себя для вызова getWindow и возвращает постоянную строку для вызова call , но, конечно, во время выполнения происходит сбой, жалуясь на

Не удалось переопределить класс: попытка изменить модификаторы метода

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

Редактировать: Из-за целевой платформы мне нужно использовать JDK 1.5 для сборки / тестирования, поэтому любое решение должно быть жизнеспособным на 1.5.

Ответы [ 2 ]

3 голосов
/ 01 декабря 2009

Какую версию JMockit вы используете? Согласно this , вы должны иметь возможность без проблем издеваться над нативными методами.

@Test
public void mockNativeMethod() {
    new MockUp<Runtime>() {
        @Mock
        @SuppressWarnings("unused")
        int availableProcessors() {
            return 999;
        }
    };
    assertEquals(999, Runtime.getRuntime().availableProcessors());
}

РЕДАКТИРОВАТЬ: Как вы заметили, это не работает с Java 1.5. Боюсь, единственное решение - обернуть ваши нативные объекты декоратором, который просто работает как сквозной. Это немного головная боль, но это позволит насмехаться / перехватывать и т.д.

1 голос
/ 05 декабря 2009

Как отметил Брайан, JMockit поддерживает макетирование нативных методов. (API ожиданий, показанный в тесте ниже, также поддерживает его.)

@Test // this only works under JDK 1.6+; JDK 1.5 does not support redefining natives
public void mockNativeMethod()
{
   new Expectations()
   {
      final System system = null;

      {
         System.nanoTime(); returns(0L);
      }
   };

   assertEquals(0, System.nanoTime());
}

Проблема, однако, заключается в том, что реализация JVMTI в JDK 1.5 не очень развита, и не поддерживает переопределение методов native.

Я понимаю, что вам необходимо развернуть производственный код в среде JDK 1.5, но это не должно препятствовать использованию JDK 1.6 в вашей среде разработки. Обычно это должно быть совершенно безопасно и легко запускать тесты на JDK 1.6 и даже компилировать весь исходный код с помощью компилятора JDK 1.6. Вам просто нужно указать javac "target" как "1.5". В Eclipse есть конфигурация «Соответствие JDK» в «Свойствах проекта -> Компилятор Java».

...