[C# 단위테스트] xUnit Mock 데이터 이용한 파일 접근하기

참조


소개

안녕하세요. 오늘은 C#에서 단위테스트에 대해서 학습해 보려고 합니다.

그 중에서도 System.IO.Abstractions 이용한 파일 접근하는 방법에 대해서 알려 드리려고 합니다.

흔히 가짜 데이터, Mock 데이터라고도 하는데요. 가짜 파일 데이터를 만들어서 xUnit 단위테스트 하는 방법에 대해서 알려 드리겠습니다.


NuGet Package 설치

  • 우선 xUnit 단위테스트 및 Mock 파일 객체를 이용한 예제 코드를 작성하려면 몇가지 NuGet Package 를 설치해야 합니다.
    • xUnit
    • xUnit.runner.visualStudio
    • System.IO.Abstractions
    • System.IO.Abstractions.TestingHelpers
  • 위 4개의 NuGet 패키지를 필수로 설치해야 합니다.

packages.config

  • 앞서, 4개의 NuGet 패키지를 모두 설치하게 되면 아래와 같이 packages.config 내용이 입력됩니다.
<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="System.IO.Abstractions" version="14.0.13" targetFramework="net48" />
  <package id="System.IO.Abstractions.TestingHelpers" version="14.0.13" targetFramework="net48" />
  <package id="xunit" version="2.4.1" targetFramework="net48" />
  <package id="xunit.abstractions" version="2.0.3" targetFramework="net48" />
  <package id="xunit.analyzers" version="0.10.0" targetFramework="net48" />
  <package id="xunit.assert" version="2.4.1" targetFramework="net48" />
  <package id="xunit.core" version="2.4.1" targetFramework="net48" />
  <package id="xunit.extensibility.core" version="2.4.1" targetFramework="net48" />
  <package id="xunit.extensibility.execution" version="2.4.1" targetFramework="net48" />
  <package id="xunit.runner.visualstudio" version="2.4.3" targetFramework="net48" developmentDependency="true" />
</packages>

테스트 대상이 되는 클래스

using System.IO;
using System.IO.Abstractions;

namespace xUnitTestProgram
{
    public class FileProcessorTestable
    {
        private readonly IFileSystem _fileSystem;

        public FileProcessorTestable() : this(new FileSystem()) { }

        public FileProcessorTestable(IFileSystem fileSystem)
        {
            _fileSystem = fileSystem;
        }

        public void ConvertFirstLineToUpper(string inputFilePath)
        {
            string outputFilePath = Path.ChangeExtension(inputFilePath, ".out.txt");

            using (StreamReader inputReader = _fileSystem.File.OpenText(inputFilePath))
            using (StreamWriter outputWriter = _fileSystem.File.CreateText(outputFilePath))
            {
                bool isFirstLine = true;

                while (!inputReader.EndOfStream)
                {
                    string line = inputReader.ReadLine();

                    if (isFirstLine)
                    {
                        line = line.ToUpperInvariant();
                        isFirstLine = false;
                    }

                    outputWriter.WriteLine(line);
                }
            }
        }
    }
}

xUnit 단위테스트 코드

  • 아래 예제 코드를 보게 되면, MockFileSystem 클래스를 이용하여 Mock 데이터를 생성합니다.
  • MockFileData 생성자 매개변수로 input 내용을 넣게 되면, line1\nline2\nline3 내용이 C:\temp\in.txt 파일에 쓰여지게 됩니다.
  • 그리고 FileProcessorTestable 의 ConvertFirstLineToUpper 메서드를 통해서 맨 앞의 line1 이 대문자 LINE으로 변경되면서, LINE1\nline2\nline3 로 내용이 변경됩니다.
  • 최종적으로 ouplines 문자열 배열 내용은 아래와 같습니다.
    • outputLines[0] = 'LINE1'
    • outputLines[1] = '\n'
    • outputLines[2] = 'line2'
    • outputLines[3] = '\n'
    • outputLines[4] = 'line3'
    • outputLines[5] = '\n'
using System.IO.Abstractions.TestingHelpers;
using Xunit;

namespace xUnitTestProgram
{
    public class FileProcessorTestableShould
    {
        [Fact]
        public void ConvertFirstLine()
        {
            var mockFileSystem = new MockFileSystem();

            var mockInputFile = new MockFileData("line1\nline2\nline3");

            mockFileSystem.AddFile(@"C:\temp\in.txt", mockInputFile);

            var sut = new FileProcessorTestable(mockFileSystem);
            sut.ConvertFirstLineToUpper(@"C:\temp\in.txt");

            MockFileData mockOutputFile = mockFileSystem.GetFile(@"C:\temp\in.out.txt");

            string[] outputLines = mockOutputFile.TextContents.Split();

            Assert.Equal("LINE1", outputLines[0]);
            Assert.Equal("line2", outputLines[2]);
            Assert.Equal("line3", outputLines[4]);
        }
    }
}

실행 결과

  • 테스트 실행 결과 모두 성공적으로 통과된 것을 확인할 수 있습니다.

728x90

이 글을 공유하기

댓글

Designed by JB FACTORY