Java 용 Fake File System 프레임 워크가 있습니까? [닫은]


83

IO 작업 (이 경우 파일 시스템)을 많이 사용하는 프로젝트에 테스트를 도입하고 있습니다. 시스템은 지속적으로 파일을 열고 / 닫고, 파일이 있는지 확인하고, 삭제하는 등의 작업을합니다.

내 테스트를 설정하고 추론하기가 어렵 기 때문에 정기적 인 조롱이별로 유용하지 않다는 것이 곧 분명해졌습니다. 반면에 가짜 파일 시스템을 사용하는 것은 굉장 할 것이고 설정하기 매우 쉽다고 생각합니다.

루비 사람들이 다시 한 것 같고 루비에서 정확히 내가 요구하는 것이 있습니다 : http://ozmm.org/posts/fakefs.html .

Java와 원격으로 유사한 것이 있습니까?


1
이것은 정적 유형 시스템이없는 언어로 더 쉽게 수행 할 수있는 애플리케이션 수준 인 것 같습니다. Java에서 File / FileInputStream / FileOutputStream은 VM을 패치하지 않으면 항상 기본 시스템의 파일 시스템을 참조합니다.
Paŭlo Ebermann

구현할 수있는 JavaFileManager 또는 FileSystemView 와 같은 인터페이스가 있지만 대부분의 프로그램에서는이를 사용하지 않습니다.
Paŭlo Ebermann

@ 1st comment : 나는 그것을 잘 알고 있습니다. 현재 File의 모든 용도를 파일 이름 만 문자열로 포함하는 내 파일 이름으로 대체했습니다. 모든 IO 로직은 IFileSystem 인터페이스에 집중되었습니다. 내가 가진 문제는 내가 필요한 방식으로 가짜 파일 시스템을 구현하는 것이 하루 종일 일한다는 것입니다 (파일 + 폴더 + 숨겨진 파일 + 이름 바꾸기 + 파일 이름에서 경로 만 가져 오기) + ...) 실제로 옳은지 확인하기 위해 테스트합니다.
삼켜 진 elysium

1
OP에서 Ruby를 언급 했으므로 여기에 C #에도 해당하는 System.IO.Abstractions 가 있다는 것을 추가하고 싶습니다 . 최근에 사용하기 시작한 System.IO.Abstractions 는 꽤 좋습니다.
julealgon 2014 년

답변:


52

Google은 Java 7의 FileSystemProvider에 대한 오픈 소스 인 메모리 구현을 보유하고 있습니다. 이 프로젝트는 jimfs라고합니다 .


Java 6 또는 이전 버전을 사용하는 경우 대안이 있습니다. 이전에 Apache Commons VFS 를 사용해 본 적이 있습니다. 언급 된 다른 응답자가 Java 7에있는 사용자 정의 FileSystemProvider와 매우 유사한 것 같습니다.

파일, RAM, S / FTP 및 Jar와 같은 여러 파일 시스템 구현 이 미리로드 되어 있습니다. 나는 또한 S3 용 플러그인을 보았다 .


6
jimfs에 +1하여 단 한 번의 변경없이 내 코드를 테스트 할 수있었습니다. ( Path실수로 사용 )
user1071136

35

같은 클래스 때문에 자바 6 및 이전 버전가 어렵다 FileFileInputStream자바 공간에서 서로 다른 "가상 파일 시스템"을 파견 할 수있는 방법을 제공합니다.

Java 7에는 가상 파일 시스템에 대한 지원이 있습니다. 사용자 정의 파일 시스템 공급자 개발을 참조하십시오 . 이것이 당신이하고 싶은 일을 할 수 있는지는 모르겠지만, 찾아보기 시작하기에 좋은 곳입니다.


Meh. 실제로 가짜 파일 시스템이없는 것 같기 때문에 최소한의 구현을 혼자서 구현할 것입니다. FileSystemProvider를 사용하여 아무것도 얻지 못합니다.

실제로 FileSystemProvider를 사용하면 이길 수 있습니다.

  • 당신은 (오픈 소스 라이선스로 출시 된 경우) 당신의 위치에있는 다른 사람들과 다른 목적으로 매우 유용 할 수있는 무언가를 구현합니다.

  • 다른 사람이 지금 작업 중일 수있는 FileSystemProvider로 전환하기로 결정하면 더 쉽게 할 수 있습니다.



6
적어도 그렇게 할 수 있습니다. 그리고 자신이 말했듯이- "설정하기 쉬울 것입니다" .
Stephen C

Meh. 실제로 가짜 파일 시스템이없는 것 같기 때문에 최소한의 구현을 혼자서 구현할 것입니다. FileSystemProvider를 사용하여 아무것도 얻지 못했습니다.
삼켜 진 elysium

@devoured elysium-내 업데이트를 참조하십시오.
Stephen C

2
쓰기와 오픈 소스 - 보내고 솔루션 추천을위한 한
WickyNilliams

19

JUnit 패키지 org.junit.rules.TemporaryFolder에서 사용할 수 있습니다 .

TemporaryFolder 규칙을 사용하면 테스트 방법이 완료 될 때 삭제되도록 보장되는 파일 및 폴더를 만들 수 있습니다 (통과 여부에 관계없이).

예:

final TemporaryFolder testFolder = new TemporaryFolder();
testFolder.create();
final Path filePath = testFolder.newFile("input.txt").toPath();
final Path dirPath = testFolder.newFolder("subfolder").toPath();

또는 .toPath()부품을 종료합니다 .

final File filePath = testFolder.newFile("input.txt");

TemporaryFolder가 메모리에 없습니다.
progonkpa

8

당신은 추상의 사용을 할 수 File귀하의 API를 변경하여 "쓰기 데이터에 어딘가에 '의 의도를 사용하여는 사용하는 OutputStream대신의를 File다음의 API a를 통과 FileOutputStream하여 생산 코드에서,하지만 그것을 통과 ByteArrayOutputStream하여 테스트에서. A ByteArrayOutputStream는 메모리 내 스트림이므로 매우 빠르며 방법을 사용하여 콘텐츠를 간단히 검사 할 수 있습니다. 테스트에 적합합니다. 데이터 ByteArrayInputStream읽고 싶다면 해당하는 것도 있습니다 .

파일 시스템은 일반적으로 매우 빠릅니다. 테스트에서 많은 파일 I / O를 수행하지 않는 한 신경 쓰지 않을 것입니다.

Java File객체 를 생성 해도 디스크에 파일이 생성 되지는 않습니다 . 즉, 다음 코드는 디스크를 변경하지 않습니다.

File f = new File("somepath"); // doesn't create a file on disk

new File ( "something")은 디스크에 파일을 생성하지 않지만 거의 모든 메서드를 실행하려고하면 파일 시스템을 사용합니다. 내가 의미하는 바를 보려면 new File ( "xyz"). getAbsolutePath ()를 사용해보십시오.
devoured elysium

1
사람들은 내 주된 관심사가 속도라고 생각하고 있다고 생각합니다. 그렇지 않습니다.
삼켜 진 elysium

1
파일 시스템과 같은 리소스를 추상화하는 것이 항상 좋습니다 (데이터 액세스 레이어를 DB에 쓰는 것과 같은 방식). 이것은 일반적으로 가장 낮은 수준의 클래스 주위에 인터페이스와 얇은 래퍼를 작성하여 수행됩니다. 프로그램의 가장 높은 수준에서 의존성 주입을 사용하면 응용 프로그램을 통해 모의 파일 시스템을 매우 쉽게 전파 할 수 있습니다 (모의 프레임 워크를 사용할 필요는없고 인터페이스의 "더미"구현).
WickyNilliams

@devouredelysium는 new File("xyz").getAbsolutePath()절대적으로 아무것도 무엇이든지 파일이있는 경로 반환 제외시켰다하지 않는 경우 가 존재합니다. 파일 시스템을 변경하지 않습니다. 파일이 존재하지 않는 경우에도 여전히 경로의 문자열을 반환하고 파일을 생성하지 않습니다. "어떤 일이 발생하는지"란 무엇을 의미 했습니까?
보헤미안

1
File내 OpenJDK 7에서 최종이 아닙니다.
Dzmitry Lazerka 2013-08-15

6

Google의 Jimfs 는 메모리 내 NIO 파일 시스템으로 테스트에 적합합니다.


4

간단한 방법은 전적으로 RAM ( Linux의 tempfs , Windows 의 RAM 디스크) 에 기반한 파일 시스템을 제공하는 시스템 방식을 사용하는 것입니다 .


속도 외에는 진정한 파일 시스템을 사용하는 것보다 더 나을지 모르겠습니다.
삼켜 진 elysium

예, 속도 (및 디스크 마모)가 주된 이유입니다. 죄송합니다. 당신의 목표를 오해했을 수도 있습니다.
Paŭlo Ebermann

1
내 목표는 테스트를 쉽게하는 것입니다. 나는 현재 성능에 관심이 없습니다.
삼켜 진 elysium

4

MockFTPServer 에는 몇 가지 가짜 파일 시스템 구현이있는 것 같습니다 (Unix / Windows).

이러한 가짜 파일 시스템 구현을 FTP 개념과는 별도로 사용할 수있는 것 같습니다. 나는 당신이 설명한 것과 똑같은 목적을 위해 이것을 지금 시도하고 있습니다.


UnixFakeFileSystem을 사용하고 있습니다. 내 파일 시스템 추상화에 대한 가짜 구현으로 매우 잘 작동합니다.

2

특정 프레임 워크에 대해서는 잘 모르겠지만 OOP 측면에서 일반적인 접근 방식은 파일 액세스 코드 (인터페이스가 풍부합니다!) 위에 추상화 된 레이어를 작성하고 일반적인 작업을 쉽게 사용할 수있는 파사드를 작성하는 것입니다. 그런 다음 현재 테스트중인 코드 아래에있는 한 레이어를 조롱 한 다음 기본적으로 가짜 파일 시스템입니다 (또는 테스트중인 코드는 그렇지 않으면 알 수 없습니다).

이를 처리하기 위해 종속성 주입 프레임 워크를 사용하는 경우 인터페이스의 가짜 구현을 위해 구성 요소를 쉽게 전환 할 수 있습니다. 제어 반전의 패턴을 따르고 테스트중인 클래스의 생성자에 종속성을 전달하면 테스트를 쉽게 수행 할 수 있습니다.

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
   }
}

나는 내 자바가 정확하기를 바랍니다. 나는 오랫동안 자바를 작성하지 않았지만, 당신은 드리프트를 얻을 것입니다. 바라건대 나는 여기서 문제를 과소 평가하지 않고 지나치게 단순합니다!

물론 이것은 당신이 진정한 단위 테스트, 즉 전체 시스템이 아니라 가능한 가장 작은 코드 단위를 테스트한다는 것을 가정하고 있습니다. 통합 테스트를 위해서는 다른 접근 방식이 필요합니다.


1
가짜 파일 시스템에는 자체 로직이 있어야합니다. 다른 파일 시스템과 마찬가지로 파일 시스템이지만 메모리에만 존재합니다. 그런 파일 시스템을 직접 프로그래밍 할 필요가 없습니다.
삼켜 진 elysium

모방하려는 파일 시스템 작업 유형은 무엇입니까? 파일 잠금? 읽기 쓰기? 또는 파일 열기, 디렉토리 존재 확인, 파일 생성과 같은 간단한 작업?
WickyNilliams

파일이 파일인지 디렉토리 (존재하는 경우)인지 확인하여 파일을 만들고 파일을 삭제하는 대부분의 간단한 작업입니다. 이것은 물론 "이 파일 이름에서 경로 가져 오기", "절대 경로에서 상대 경로 가져 오기"등과 같은 여러 폴더 및 작업을 지원하는 동시에
devoured elysium

내가 말했듯이 물리적 파일 시스템 주위에 absrtaction을 만들고 항상 앱 전체에서 (항상 인터페이스에 대해 코딩) 사용합니다. 그런 다음 종속성 주입을 사용하여 테스트 대상을 전파하십시오. :) 나는 단조로운 작업을 알고 있지만, 프로그래머로서 우리는 우려의 깨끗한 분리를 얻기 위해이 일을해야하고 테스트 용이성의 용이성을 허용
WickyNilliams

당신은 여기서 요구되는 것을 정말로 얻지 못하고 있습니다. 가짜 파일 시스템을 찾고 있다면 이미 내 앱에서 전체 파일 시스템을 추상화 했기 때문일 것입니다 (OP의 주석에 명시된대로). 나는 단지 내 테스트에서 사용하는 파일 시스템의 가짜 구현 .. 필요
먹어 엘리시움

2

Arquillian 프로젝트의 ShrinkWrap 은 메모리 파일 시스템에 NIO 규격을 포함하는 것으로 보입니다.

다음을 수행하여 간단한 메모리 파일 시스템을 만들 수 있습니다.

FileSystem fs = ShrinkWrapFileSystems.newFileSystem(ShrinkWrap.create(GenericArchive.class))

이 파일을 지원합니까 : // 프로토콜을 ... 문서를 찾을 수 없습니다
마르코 Vasapollo


0

나는 "Fake java FileSystem"을 검색하고이 질문을 발견했습니다. 불행히도 이것이 내가 찾은 전부입니다. 그래서이 가짜 파일 시스템을 직접 작성했습니다 : https://github.com/dernasherbrezon/mockfs

파일 읽기 / 쓰기 중 IOExceptions를 시뮬레이션하는 데 사용하고 있습니다. 예를 들어 "디스크 공간 없음"으로 인해 IOException이 발생할 수 있으며, 이는 다른 방법으로 시뮬레이션하는 것이 거의 불가능합니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.