Тестовый класс с использованием File и FileInputStream с Mockito/PowerMockito

Я хотел бы издеваться над объектом File и FileInputStream для теста JUnit.

Допустим, у нас есть парсер. Извне парсер доступен только через метод parse(File myFile). Другие методы, такие как readMyStream.... являются закрытыми.

Пример кода:

public class Parser {

   public HashMap<String, String> parse(File myFile) throws Exception {
         HashMap<String, String> myConfig;
         Config config;

         try {
             //this line gives me a headache
             FileInputStream myFileInputStream = new FileInputStream(myFile);

             configStream = readMyStream(myFileInputStream);
               ..........
         } catch (FileNotFoundException e) {
                throw e;
         }
         return myConfig;
   }
   //reads the stream 
   private Config readMyStream(FileInputStream myFileInputStream) {
      Config config;    

      ...JDOM stuff....    

      return config;
   }
}

Проблемы, с которыми я сталкиваюсь:

  • как утвердить файловый объект FileInputStream (PowerMockito), как этот файл, принадлежит этому FileInputStream со следующим содержимым
  • как издеваться над частным методом (Mockito/PowerMockito)

пример Mocking/не работает :)......

public class ParserTest {

   @Test
   public final void testParse() {
      File MOCKEDFILE = PowerMockito.mock(File.class);
      PowerMockito.when(MOCKEDFILE.exists()).thenReturn(true);
      PowerMockito.when(MOCKEDFILE.isFile()).thenReturn(true);
      PowerMockito.when(MOCKEDFILE.isDirectory()).thenReturn(false);
      PowerMockito.when(MOCKEDFILE.createNewFile()).thenReturn(true);
      PowerMockito.when(MOCKEDFILE.length()).thenReturn(11111111L);

      //what about the path of MOCKEDFILE which isn't existing
      PowerMockito.when(MOCKEDFILE.getPath()).thenReturn(?????);

      //how to assign a File an FileInputStream? (I thought something like)
      PowerMockito.mockStatic(FileInputStream.class);
      FileInputStream MOCKEDINPUTSTREAM = PowerMockito.mock(FileInputStream.class);
      PowerMockito.whenNew(FileInputStream.class).withArguments(File.class).thenReturn(MOCKEDINPUTSTREAM);

      //how to mock the private method readMyStream
   }

person Funky Monkey    schedule 17.10.2012    source источник


Ответы (1)


Вместо того, чтобы издеваться над File, я бы предложил использовать правило TemporaryFolder и создавать/не создавать файл соответствующим образом.

В моих предыдущих проектах мы написали класс FileInputStreamSupplier, который используется для создания класса FileInputStream. Затем этот класс можно смоделировать, чтобы предоставить смоделированный FileInputStream, позволяющий тестировать поведение. Как правило, вы можете заставить свой класс взять Supplier<FileInputStream> (используя Guava) и высмеять это.

person John B    schedule 17.10.2012
comment
не могли бы вы опубликовать пример кода... Я не понимаю, как правило JUnit TemporaryFolder должно быть связано с моим вопросом. - person Funky Monkey; 18.10.2012
comment
Вы можете использовать TemporaryFolder для создания File во время выполнения, которое соответствует потребностям теста, будь то файл, существующий (создайте его), имеет определенное имя, расширение, размер и т. д. Какой сценарий вы пытаетесь протестировать, который не будет быть тестируемым, используя это в сочетании с Supplier<FileInputStream>? - person John B; 18.10.2012
comment
Я мог бы написать что-то вроде @Rule public TemporaryFolder tmpFolder = new TemporaryFolder(); @Test public void testParse_xyas() { File tmpFile = tmpFolder.newFile(FILENAME); //now how to assert my tmpFile an InputStream?? }.. - person Funky Monkey; 18.10.2012
comment
Что значит быть assert my tmpFile an InputStream? Файл не является InputStream. InputStream будет создан вокруг файла в строке new FileInputStream(file). Если вам нужно имитировать FileInputStream, снова используйте Поставщика, о котором я упоминал выше. - person John B; 18.10.2012
comment
Найдите эту ссылку очень полезной: JUnit Rule Entity Manager< /а> - person Jing Li; 19.06.2014