2013-03-13 3 views
1

Я успешно использовал Specs2 для тестирования сериализации в файл, но в тесте используется реальный файл (записанный в/tmp /). Я бы предпочел не касаться диска только для теста. Есть ли способ использовать насмешливый файл?Могу ли я использовать файл mock в моем тесте Specs2 для записи в файл? Если да, то как?

def serializeAndDeserializeFromDatafile[X <: CaseClass : Manifest](old: X, maybeGrater: Option[AvroGrater[X]] = None): X = { 
val g = maybeGrater.getOrElse(grater[X]) 

//val outfile = mock[File] 
val outfile = new File("/tmp/file1.avro") 

g.serializeToDataFile(outfile, old) //Serialize to file 

val infile = outfile 
g.asObjectFromDataFile(infile)  //Deserialize from file 
} 

Я попытался с помощью Mockito издеваться мой outfile (в закомментированной строке выше). В моей наивной попытке я могу создать Mock for File, hashCode: 1583021903, но, кажется, это null, когда я пытаюсь сериализовать.

Я думаю, что мне не хватает «заглушки», но я не могу найти примеров, которые достаточно похожи, чтобы предложить решение. Любая помощь будет оценена по достоинству.

ответ

1

У меня есть программа (автономная написанная с использованием Akka), которая активно занимается файловой системой. Я написал его с использованием ScalaIO (а не собственной библиотеки Java java.io._ классов). ScalaIO включает, помимо прочего, RamFileSystem, который позволяет вам издеваться над содержимым и операциями файловой системы способами, которые отражают реальные действия файловой системы без задействования системных вызовов файловой системы и ввода/вывода.

+0

Удивительный, спасибо.Это то, на что я надеялся, но я быстро споткнулся: 'val fs = new RamFileSystem (separator ="/") println (" filesys: "+ fs) val path = fs ("/tmp/", '/ «) Println ("путь:" + путь) Println ("ISFILE "+ path.isFile) вал mockedFile = path.createFile() Println (" mockedFile" + mockedFile) Println ("ISFILE" + mockedFile.isFile) val outfile = mockedFile.fileOption println ("outfile:" + outfile) 'говорит мне, что' mockedFile' является файлом, но 'outfile: Option [File]' является 'PathType', таким образом возвращая' None' вместо необходимого 'java.io.File' –

+0

Просим прощения за форматирование. tl; dr: Должен ли я ожидать получить «java.io.File» от такого рода макета (например, «RamPath»)? –

+0

№ Как это могло быть? Для этого потребуется драйвер файловой системы на уровне ОС. Но ScalaIO - намного более богатый API для операций ввода-вывода и файлов. –

1

Не могли бы вы использовать OutputStream/InputStream вместо файлов?

Пример:

val out:OutputStream = null 
// val testOut = new ByteArrayOutputStream() 
// val realOut = new FileOutputStream(new File("/tmp/file1.avro")) 

g.serializeToOutputStream(out, old) //Serialize to file 

val in:InputStream = null 
// val testIn = new ByteArrayInputStream(testOut.toByteArray) 
// val realIn = new FileInputStream(new File("/tmp/file1.avro")) 

g.asObjectFromInputStream(in)  //Deserialize from file 
+0

Спасибо, но я так не думаю: базовые классы принимают только «Файл». По крайней мере, не очевидно, как «макет» в том, как вы предлагаете. Прежде чем использовать Specs2 для тестирования этого, я попытался «издеваться» над потоком, как вы предлагаете, но увязнул, пытаясь прочитать границы записей из двоичного кода без 'datafilereader'. Использование классов Avro более низкого уровня для записи avros выглядит/выглядит очень по-другому, и у меня уже есть тесты для такой сериализации. Здесь мне нужно протестировать этот компонент и его использование базовых высокоуровневых методов класса datafilewriter/datafilereader. Может быть, издеваются над этими классами? –

+0

Хм, может быть, мое предыдущее усилие не работало для потоков avros, которые не поместились бы в памяти, но для этого небольшого теста я попробую еще раз ... Тем не менее хотелось бы знать, как использовать Mockito. –

1

Вы можете издеваться оттуда File, но это не значит, что все будет работать нормально. По умолчанию, когда вы вызываете метод на макет, он возвращает null (или 0 для значения int).

Так что если функция, которую вы тестируете, вызывает один из методов File, вам необходимо будет предоставить разумные значения по умолчанию. Например:

val f = mock[File] 

f.createNewFile returns true 
f.isFile returns true 
f.list returns Array("child1", "child2") 

Это, как говорится, если ваш grater объект действительно нуждается в функциональный файл на запись, это может быть невозможно действительно дразнить это.

+0

Это половина ответа без ответа :). Не могли бы вы уточнить, откуда берется «нуль»? – Eric

+0

Это уже полезно для меня :) Я не эксперт, поэтому единственное, что я могу добавить в RE: «null», заключается в том, что ошибка, которую вы выбрали, представляет собой исключение сериализации Salat-Avro в «SingleAvroGrater.scala» (прежде всего касается «индексированных полей», но не создания файла или установки значений полей). И если я установил возвращаемое по умолчанию значение 'mock [File]' to 'None', компилятор жалуется, что его нельзя отнести к java' Boolean' (я остановился там). Благодаря вашему примеру я теперь вижу, что есть большие трудности в насмешке таким образом, и реальный файл выглядит более приемлемым. И спасибо за Specs2! –