단위 테스트를 작성하기 위해 C #에서 파일 시스템을 모방하는 라이브러리 또는 메소드가 있습니까? 현재의 경우 특정 파일이 있는지 확인하고 생성 날짜를 읽는 방법이 있습니다. 앞으로는 그 이상이 필요할 수 있습니다.
단위 테스트를 작성하기 위해 C #에서 파일 시스템을 모방하는 라이브러리 또는 메소드가 있습니까? 현재의 경우 특정 파일이 있는지 확인하고 생성 날짜를 읽는 방법이 있습니다. 앞으로는 그 이상이 필요할 수 있습니다.
답변:
편집 : NuGet 패키지를 설치하십시오 System.IO.Abstractions
.
이 답변이 처음 수락되었을 때이 패키지는 존재하지 않았습니다. 아래의 역사적 맥락에 대한 원래 답변이 제공됩니다.
인터페이스를 만들어서 할 수 있습니다.
interface IFileSystem { bool FileExists(string fileName); DateTime GetCreationDate(string fileName); }
System.IO.File.Exists () 등을 사용하는 '실제'구현을 작성합니다. 그런 다음 조롱 프레임 워크를 사용하여이 인터페이스를 조롱 할 수 있습니다. 나는 Moq를 추천한다 .
편집 : 누군가가 이것을하고 친절하게 온라인으로 여기에 게시했습니다 .
이 방법을 사용하여 IClock 인터페이스 (시간 흐름을 제어 할 수있는 테스트에 실제로 유용합니다!)에서 DateTime.UtcNow를 조롱하고보다 전통적으로 ISqlDataAccess 인터페이스를 사용했습니다.
또 다른 방법은 TypeMock 을 사용하는 것입니다 . 이렇게하면 클래스에 대한 호출을 가로 채고 스텁 할 수 있습니다. 그러나 이것은 비용이 들며, 실행하기 위해서는 전체 팀의 PC와 빌드 서버에 설치해야하며, mscorlib를 스터브 할 수 없으므로 System.IO.File에서는 작동하지 않을 것입니다 .
또한 특정 방법을 단위로 테스트 할 수 없다는 점을 받아들이고 느리게 실행되는 별도의 통합 / 시스템 테스트 스위트에서 테스트 할 수 있습니다.
이 가상의 라이브러리가 이제 존재합니다. System.IO.Abstractions 용 NuGet 패키지가 있으며, System.IO 네임 스페이스를 추상화합니다.
또한 작성시에는 부분적으로 만 구현되지만 매우 좋은 시작점이되는 일련의 테스트 도우미 System.IO.Abstractions.TestingHelpers가 있습니다.
파일 시스템에서 필요한 것을 정의한 다음 해당 기능에 대한 래퍼를 작성하는 계약을 작성해야 할 것입니다. 그 시점에서 구현을 조롱하거나 스텁 아웃 할 수 있습니다.
예:
interface IFileWrapper { bool Exists(String filePath); }
class FileWrapper: IFileWrapper
{
bool Exists(String filePath) { return File.Exists(filePath); }
}
class FileWrapperStub: IFileWrapper
{
bool Exists(String filePath)
{ return (filePath == @"C:\myfilerocks.txt"); }
}
시스템 네임 스페이스에서 주로 사용되는 유형에 대한 래퍼를 제공 하므로 http://systemwrapper.codeplex.com/ 을 사용하는 것이 좋습니다.
나는 이것에 대한 다음과 같은 솔루션을 보았습니다.
내가 쓰고있는 것에 따라 위의 모든 방법을 사용하게됩니다. 그러나 대부분의 경우 IO에 도달하는 단위 테스트를 작성할 때 추상화가 잘못되었다고 생각합니다.
System.IO.Abstractions 및 System.IO.Abstractions.TestingHelpers 를 사용 하면 다음과 같습니다.
public class ManageFile {
private readonly IFileSystem _fileSystem;
public ManageFile(IFileSystem fileSystem){
_fileSystem = fileSystem;
}
public bool FileExists(string filePath){}
if(_fileSystem.File.Exists(filePath){
return true;
}
return false;
}
}
테스트 클래스에서 MockFileSystem ()을 사용하여 파일을 모방하고 다음과 같이 ManageFile을 설정합니다.
var mockFileSysteme = new MockFileSystem();
var mockFileData = new MockFileData("File content");
mockFileSysteme.AddFile(mockFilePath, mockFileData );
var manageFile = new ManageFile(mockFileSysteme);
예를 들어 코드베이스가 이미 고정되어 있기 때문에 코드베이스를 변경할 필요없이 Microsoft Fakes 를 사용하여이를 수행 할 수 있습니다 .
먼저 System.dll 또는 다른 패키지에 대한 가짜 어셈블리 를 생성 한 후 다음과 같이 예상되는 결과를 조롱합니다.
using Microsoft.QualityTools.Testing.Fakes;
...
using (ShimsContext.Create())
{
System.IO.Fakes.ShimFile.ExistsString = (p) => true;
System.IO.Fakes.ShimFile.ReadAllTextString = (p) => "your file content";
//Your methods to test
}
파일 시스템을 어떻게 조롱할지 잘 모르겠습니다. 할 수있는 일은 테스트에 필요한 구조로 폴더 등을 만드는 테스트 픽스처 설정을 작성하는 것입니다. 테스트가 실행 된 후 분해 방법으로 정리할 수 있습니다.
추가 편집 : 이것에 대해 조금 더 생각할 때,이 유형의 메소드를 테스트하기 위해 파일 시스템을 모방하고 싶지는 않습니다. 파일 시스템을 모의하여 특정 파일이 존재하는 경우 true를 반환하고 해당 파일이 존재하는지 확인하는 방법을 테스트 할 때 파일 시스템을 사용하면 아무 것도 테스트하지 않습니다. 파일 시스템을 조롱하는 것은 파일 시스템에 종속 된 메소드를 테스트하려고하지만 파일 시스템 활동이 테스트중인 메소드의 필수 요소가 아닌 경우에 유용합니다.
특정 질문에 대답하려면 : 아니요, 파일 I / O 호출 (내가 아는)을 조롱 할 수있는 라이브러리가 없습니다. 즉, 유형을 "적절하게"단위 테스트하려면 유형을 정의 할 때이 제한 사항을 고려해야합니다.
"적절한"단위 테스트를 정의하는 방법에 대한 간단한 참고 사항. 단위 테스트를 통해 알려진 입력을 제공 한 예상 출력 (예외, 메소드 호출 등)을 얻을 수 있는지 확인해야한다고 생각합니다. 이를 통해 단위 테스트 조건을 일련의 입력 및 / 또는 입력 상태로 설정할 수 있습니다. 내가 찾은 가장 좋은 방법은 인터페이스 기반 서비스와 종속성 주입을 사용하여 형식 외부의 각 책임이 생성자 또는 속성을 통해 전달 된 인터페이스를 통해 제공되도록하는 것입니다.
따라서 이것을 염두에두고 질문으로 돌아가십시오. 나는 단순히 mscorlib 파일 시스템 메소드의 정면에 IFileSystemService
대한 FileSystemService
구현 과 함께 인터페이스를 작성하여 파일 시스템 호출을 조롱했습니다 . 그런 다음 내 코드 IFileSystemService
는 mscorlib 유형 대신 오히려 를 사용합니다 . 이를 통해 FileSystemService
응용 프로그램이 실행 중일 때 표준을 연결할 수 있습니다 .IFileSystemService
단위 테스트를 있습니다. 응용 프로그램 코드는 실행 방식에 관계없이 동일하지만 기본 인프라를 통해 해당 코드를 쉽게 테스트 할 수 있습니다.
mscorlib 파일 시스템 개체 주위에서 래퍼를 사용하는 것은 고통 스럽지만 이러한 특정 시나리오에서는 테스트가 훨씬 쉽고 안정적으로 진행되므로 추가 작업을 수행 할 가치가 있습니다.
테스트를 위해 인터페이스를 만들고 조롱하는 것이 가장 깨끗한 방법입니다. 그러나 대안으로 Microsoft Moles 프레임 워크를 살펴볼 수 있습니다 .
일반적인 솔루션은 일부 추상 파일 시스템 API (예 : Apache Commons VFS for Java)를 사용합니다. 모든 응용 프로그램 논리는 API를 사용하고 단위 테스트는 스텁 구현 (메모리 내 에뮬레이션 등)으로 실제 파일 시스템을 조롱 할 수 있습니다.
C #의 경우 유사한 API가 있습니다. NI.Vfs 는 Apache VFS V1과 매우 유사합니다. 로컬 파일 시스템과 메모리 내 파일 시스템 모두에 대한 기본 구현이 포함되어 있습니다 (마지막 시스템은 상자에서 단위 테스트에 사용될 수 있음).