существуют ли фреймворки fake file system для java?

<p>я представляю тесты в проекте, в котором интенсивно используются операции io (в данном случае файловая система). система постоянно открывает/закрывает файлы, проверяет, существуют ли файлы, удаляет их и так далее.</p><p>вскоре стало очевидным, что регулярный макет не принесет особой пользы, поскольку это затруднит настройку моих тестов и их рассуждение. с другой стороны, иметь поддельную файловую систему было бы здорово, и я думаю, ее довольно легко настроить.</p><p>похоже, что ruby ребята сделали это снова, и именно в ruby я и просил: <a href="http://ozmm.org/posts/fakefs.html">http://ozmm.org/posts/fakefs.html</a> .</p><p>есть что-нибудь похожее для java?</p>

<p>google имеет открытую реализацию в filesystemprovider java 7 в памяти. <a href="https://github.com/google/jimfs">проект называется jimfs</a> .</p><hr><p>если вы используете java 6 или более раннюю версию, есть альтернатива: раньше я пользовался <a href="http://commons.apache.org/vfs/">apache commons vfs</a> с большим успехом. похоже, что это очень похоже на пользовательский filesystemprovider, о котором упоминал другой ответчик в java 7.</p><p>он поставляется <a href="http://commons.apache.org/vfs/filesystems.html">предварительно загруженный</a> с несколькими реализациями файловой системы: file, ram, s/ftp и jar и многие другие. я также видел <a href="http://code.google.com/p/vfs-s3/">плагин для s</a> .</p>

<p>в java 6 и более ранних версиях это сложно, потому что такие классы, как <code>file</code> и <code>fileinputstream</code>, не предоставляют способа отправки в разные "виртуальные файловые системы" в пространстве java.</p><p>в java 7 есть поддержка виртуальных файловых систем; см. <a href="http://download.oracle.com/javase/7/docs/technotes/guides/io/fsp/filesystemprovider.html">разработка собственного провайдера файловой системы</a> . я не знаю, позволит ли это вам делать то, что вы хотите делать, но это хорошее место, чтобы начать искать.</p><hr><blockquote> <p>мех. учитывая тот факт, что на самом деле не существует какой-либо поддельной файловой системы, я полагаю, что сам реализую минимальную реализацию. я ничего не выигрываю с помощью filesystemprovider</p> </blockquote><p>на самом деле, вы действительно выигрываете, используя filesystemprovider:</p><ul> <li> <p>вы реализуете что-то, что (если выпущено по лицензии с открытым исходным кодом) может быть очень полезным для других людей на вашей должности и для других целей.</p> </li> <li> <p>вы облегчите себе задачу, если решите переключиться на filesystemprovider, над которым сейчас может работать кто-то другой.</p> </li> </ul>

<p>вы можете использовать <code>org.junit.rules.temporaryfolder</code> из пакета <a href="http://junit.org/apidocs/org/junit/rules/temporaryfolder.html">junit</a> :</p><blockquote> <p>правило temporaryfolder позволяет создавать файлы и папки, которые гарантированно удаляются после завершения метода тестирования (независимо от того, прошел он или нет):</p> </blockquote><p><strong> пример: </strong></p><pre><code>final temporaryfolder testfolder = new temporaryfolder(); testfolder.create(); final path filepath = testfolder.newfile("input.txt").topath(); final path dirpath = testfolder.newfolder("subfolder").topath(); </code></pre><p>либо выйдите из части <code>.topath()</code>:</p><pre><code>final file filepath = testfolder.newfile("input.txt"); </code></pre>

<p>вы можете абстрагироваться от использования <code>file</code>, используя намерение "где-то записывать данные", изменив свой api на использование <code>outputstream</code> вместо <code>file</code>, затем передать api <code>fileoutputstream</code> в свой рабочий код, но передать его <a href="http://docs.oracle.com/javase/7/docs/api/java/io/bytearrayoutputstream.html">( <code>bytearrayoutputstream</code></a> из ваших тестов. <code>bytearrayoutputstream</code> - это поток в памяти, поэтому он очень быстрый, и вы можете просто проверить его содержимое с помощью его методов - он идеально подходит для тестирования. также есть соответствующее <code>bytearrayinputstream</code>, если вы хотите <em> прочитать </em> данные.</p><p>файловые системы, как правило, довольно быстрые - если бы вы не выполняли много файлового ввода-вывода в своих тестах, я бы не стал беспокоиться.</p><p>обратите внимание, что создание объекта java <code>file</code> <em> не создает </em> файла на диске, т.е. следующий код не вызывает никаких изменений в диск:</p><pre><code>file f = new file("somepath"); // doesn't create a file on disk </code></pre>

<p> <a href="https://github.com/google/jimfs">jimfs</a> от google - файловая система nio в памяти, которая отлично подходит для тестов.</p>

<p>простой способ состоит в том, чтобы использовать системный способ предоставления файловой системы, полностью основанной на ram - <a href="http://en.wikipedia.org/wiki/tmpfs">tempfs</a> в linux, <a href="http://en.wikipedia.org/wiki/ram\_disk">ram-диск</a> в windows.</p>

<p> <a href="http://mockftpserver.sourceforge.net/apidocs/org/mockftpserver/fake/filesystem/filesystem.html">mockftpserver</a> , кажется, имеет несколько реализаций поддельной файловой системы (unix/windows)</p><p>похоже, что вы можете использовать эти поддельные реализации файловой системы совершенно отдельно от любых концепций ftp. я пытаюсь сделать это сейчас для тех же целей, что и вы.</p>

<p>я не уверен насчет конкретных фреймворков, но общий подход с точки зрения oop будет состоять в том, чтобы написать несколько абстрактных слоев поверх любого кода доступа к файлу (интерфейсы в изобилии!) и, возможно, фасад для облегчения использования общие операции. затем вы просто макетируете один слой ниже кода, который вы сейчас тестируете, и тогда это по сути фальшивая файловая система (или, по крайней мере, код, который вы тестируете, иначе не будет знать).</p><p>если вы захотите использовать инфраструктуру внедрения зависимостей для этого, это упростит возможность переключения компонентов для искусственной реализации интерфейса. если вы будете следовать шаблонам инверсии управления, передавая любые зависимости в конструктор класса, который вы тестируете, это также облегчит тестирование.</p><pre><code>public interface ifilesystem { ifilehandle load(string path); //etc } public class classbeingtested { public classbeingtested(ifilesystem filesystem) { //assign to private field } public void dosomethingwithfilesystem() { //utilise interface to file system here //which you could easily mock for testing purposes //by passing a fake implementation to the constructor } } </code></pre><p>я надеюсь, что моя java верна, я давно не писал java, но, надеюсь, вы поймете, что это дрейф. надеюсь, я не недооцениваю проблему здесь и являюсь чрезмерно упрощенным!</p><p>конечно, все это предполагает, что вы имеете в виду истинное модульное тестирование, то есть тестирование наименьших возможных блоков кода, а не всей системы. для интеграционного тестирования нужен другой подход.</p>

<p> <a href="http://arquillian.org/modules/shrinkwrap-shrinkwrap/">shrinkwrap из проекта arquillian</a> предполагает включение nio-совместимого в память файловой системы</p><p>вы можете создать простую в памяти файловую систему, выполнив следующие действия:</p><pre><code>filesystem fs = shrinkwrapfilesystems.newfilesystem(shrinkwrap.create(genericarchive.class)) </code></pre>

<p>две другие файловые системы в памяти для java:</p><p> <a href="https://github.com/marschall/memoryfilesystem">memoryfilesystem</a> </p><p> <a href="https://github.com/sbridges/ephemeralfs">ephemeralfs</a> </p><p>оба реализуют api файловой системы nio.2.</p>

<p>я погуглил "fake java filesystem" и нашел этот вопрос. к сожалению это все, что я нашел. поэтому я написал эту поддельную файловую систему самостоятельно: <a href="https://github.com/dernasherbrezon/mockfs">https://github.com/dernasherbrezon/mockfs</a> </p><p>я использую его для имитации ioexception во время чтения/записи в файлы. ioexception может произойти, например, из-за "отсутствия места на диске", которое практически невозможно смоделировать другими средствами.</p>