2015-01-16 2 views
0

Я пытаюсь издеваться над методом, который создает локальную переменную, пытается что-то и выполняет регистрацию, если генерируется исключение. Вот фрагмент кода:Mocking with JMockit throws NullPointerException для локальных переменных внутренних классов

public void myFunction() { 
    //Some stuff 
    try { 
     new File("foo").getAbsoluteFile(); 
    } catch (SecurityException e) { 
     //Do some logging 
    } 
} 

Я хотел бы, чтобы дразнить это поведение протоколирования с использованием JMockit (с использованием версии 1.8, если это имеет значение). Таким образом, я создал следующий тест:

@Test(expected=SecurityException.class) 
public void testAbsoluteFile(
     @Injectable final File file 
) throws IOException { 

    new Expectations(File.class){{ 
     new File(anyString); 
     result = file; 
     file.getAbsoluteFile(); 
     result = new SecurityException(); 
    }}; 

    myFunction(); 
} 

Беда в том, что это, кажется, дает мне NullPointerException на внутренней работе File.getAbsoluteFile(), которые я нахожу абсолютно причудливым:

java.lang.Exception: Unexpected exception, expected<java.lang.SecurityException> but was<java.lang.NullPointerException> 
Caused by: java.lang.NullPointerException 
    at java.io.Win32FileSystem.slashify(Win32FileSystem.java:56) 
    at java.io.Win32FileSystem.resolve(Win32FileSystem.java:330) 
    at java.io.File.getAbsolutePath(File.java:556) 
    at java.io.File.getAbsoluteFile(File.java:572) 
    at com.vue.rescoreservice.ExpectationTest.myFunction(ExpectationTest.java:39) 
    at com.vue.rescoreservice.ExpectationTest.testAbsoluteFile(ExpectationTest.java:33) 

Это кажется очень странным, как он говорит, что локальная переменная в классе Win32FileSystem (внутренний класс не в типичном Java API) бросает исключение NullPointerException, когда оно никогда не делалось раньше.

линии, которые находятся в трассировки стека следующим образом:

//In myFunction() 
new File("foo").getAbsoluteFile(); 

и

//In testAbsoluteFile() 
myFunction(); 

Почему это происходит? И как я могу сделать так, чтобы JMockit не выбрасывал исключение NullPointerException для локальных переменных внутренних классов?

+0

Можете ли вы предоставить дополнительную информацию? Журнал ошибок указывает на две области вашего кода в ExpectationTest.java, строка 59 и 65. Каковы эти строки? – user3334871

+0

@ user3334871 Я добавил его к вопросу – Thunderforge

ответ

3

Эта проблема исправлена ​​в последней версии jMockit (1.14). Если вы не хотите сейчас мигрировать, можно исправить тест в 1.8 (см. Код ниже).

В этом случае @Injectable не требуется. Конструктор File издевается над ожиданием и требует издевательства над самим классом вместо одного экземпляра. В этом случае поведение эквивалентно @Mocked (но файл будет частично издеваться в соответствии с вызовами в блоке Expectations).

Предложение catch в myFunction необходимо перебросить SecurityException, чтобы пройти тест.

@Test(expected=SecurityException.class) 
public void testAbsoluteFile() throws IOException { 
    new Expectations(File.class) {{ 
     File file = new File(anyString); 

     file.getAbsoluteFile(); 
     result = new SecurityException(); 
    }}; 

    myFunction(); 
} 

Если вы предпочитаете объявить макет в качестве параметра, он также будет работать, но файл не будет частично издевался (все методы будут издевались).

@Test(expected=SecurityException.class) 
public void testAbsoluteFile(@Mocked final File file) throws IOException { 

    new Expectations(){{ 
     new File(anyString); 

     file.getAbsoluteFile(); 
     result = new SecurityException(); 
    }}; 

    myFunction(); 
} 
+0

Причина, по которой тест не прошел в java.io.Win32FileSystem, заключается в том, что класс File не правильно издевается и реальная реализация вызывается с anyString в качестве параметра. Значение anyString равно null, поэтому с ошибкой NullPointerException. –

+0

Отличный ответ! Просто nitpick: лучше всего частично издеваться над файлом 'File' для определенного имени файла here =>' new Expectations (File.class) {{new File ("foo"). getAbsoluteFile(); result = new SecurityException(); }}; ' –

0

Обновление на @ Marc-André.

В моем случае с JMockit 1,25 я должен был определить переменный файл за пределами ожиданий, оставляя это нравится:

@Test(expected=SecurityException.class) 
public void testAbsoluteFile() throws IOException { 
    File file = new File(""); 
    new Expectations(File.class) {{ 
     file.getAbsoluteFile(); 
     result = new SecurityException(); 
    }}; 

    myFunction(); 
} 

Может быть, это было изменением на JMockit до ответа.

Смежные вопросы