단위 테스트를 위해 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/ 을 사용하는 것이 좋습니다.


답변

나는 이것에 대한 다음과 같은 솔루션을 보았습니다.

  • 단위 테스트가 아닌 통합 테스트를 작성하십시오. 이것이 작동하려면 다른 테스트 방해에 대해 걱정하지 않고 물건을 덤프 할 수있는 폴더를 만드는 간단한 방법이 필요합니다. 사용할 테스트 메소드 폴더마다 고유 한 간단한 TestFolder 클래스가 있습니다.
  • 모의 가능한 System.IO.File을 작성하십시오. 그것이 IFile.cs 입니다. 이것을 사용하면 종종 모의 진술을 작성할 수 있음을 입증하는 테스트로 끝나지만 IO 사용량이 적을 때 사용합니다.
  • 추상화 계층을 검사하고 클래스에서 파일 IO를 추출하십시오. 이를위한 인터페이스를 만듭니다. 나머지는 통합 테스트를 사용하지만 매우 작습니다. ioThingie.loadSettings ()와 같이 의도를 작성하십시오.
  • System.IO.Abstractions . 나는 이것을 아직 사용하지는 않았지만, 내가 가지고 놀기에 가장 흥분되는 것입니다.

내가 쓰고있는 것에 따라 위의 모든 방법을 사용하게됩니다. 그러나 대부분의 경우 IO에 도달하는 단위 테스트를 작성할 때 추상화가 잘못되었다고 생각합니다.


답변

System.IO.AbstractionsSystem.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
}