[C# 단위테스트] xUnit 파일시스템(IFileSystem) Mock데이터 사용법

참조


소개

  • 안녕하세요. 오늘은 C# 단위테스트에 대해서 학습해 보려고 합니다.
  • 그 중에서도 xUnit 을 이용하여, 흔히 가짜객체? 라고 하는 Mock 데이터를 사용하여 단위테스트 하는 방법에 대해서 코드를 통해 알려 드리려고 합니다.
  • Mock 데이터는 실제 데이터가 아닌, 단위테스트를 하기 위한 가짜 데이터를 의미하고, 이를 만들기 쉽게 IFileSystem 인터페이스를 C# 에서 NuGet 패키지를 통해 제공해 주고 있습니다.

IFileSystem 이란?

  • System.Web.Abstractions 와 같지만 테스트 가능한 IO 접근을 위한 System.IO 라고 합니다.
  • 라이브러리의 핵심에는 IFileSystem 및 FileSystem이 있습니다.
  • File.ReadAllText와 같은 메서드를 직접 호출하는 대신, IFileSystem.File.ReadAllText를 사용합니다.

IFileSystem NuGet 설치

  • IFileSystem 인터페이스를 사용하려면 System.IO.Abstractions NuGet 패키지를 설치해야 합니다.
dotnet add package System.IO.Abstractions

IFileSystem 예제 코드


ComponentNoTestable.cs

using System;
using System.IO;

namespace FileSystemLib
{
    public class ComponentNoTestable
    {
        public void Validate()
        {
            foreach (var textFile in Directory.GetFiles(@"c:\", "*.txt", SearchOption.TopDirectoryOnly))
            {
                var text = File.ReadAllText(textFile);
                if (text != "Testing is awesome.")
                    throw new NotSupportedException("We can't go on together. It's not me, it's you.");
            }
        }
    }
}

ComponentTestable.cs

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

namespace FileSystemLib
{
    public class ComponentTestable
    {
        private readonly IFileSystem _fileSystem;

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

        public ComponentTestable() : this(fileSystem: new FileSystem())
        {
        }

        public void Validate()
        {
            foreach (var textFile in _fileSystem.Directory.GetFiles(@"c:\", "*.txt", SearchOption.TopDirectoryOnly))
            {
                var text = _fileSystem.File.ReadAllText(textFile);
                if (text != "Testing is awesome.")
                    throw new NotSupportedException("We can't go on together. It's not me, it's you.");
            }
        }
    }
}

FileSystemLib.Tests - ComponentTestableSpec.cs

using FluentAssertions;
using System;
using System.Collections.Generic;
using System.IO.Abstractions;
using System.IO.Abstractions.TestingHelpers;
using Xunit;

namespace FileSystemLib.Tests
{
    public class ComponentTestableSpec
    {
        [Fact]
        public void Should_Throw_NotSupportedException()
        {
            // Arrange
            IFileSystem fileSystem = new MockFileSystem(new Dictionary<string, MockFileData>
            {
                { @"c:\myfile.txt", new MockFileData("Testing is meh.") },
                { @"c:\demo\jQuery.js", new MockFileData("some js") },
                { @"c:\demo\image.gif", new MockFileData(new byte[] { 0x12, 0x34, 0x56, 0xd2 }) }
            });
            var component = new ComponentTestable(fileSystem);

            // Act
            Action act = () => component.Validate();

            // Assert
            act.Should().Throw<NotSupportedException>();
        }

        [Fact]
        public void ShouldNot_Throw_NotSupportedException()
        {
            // Arrange
            IFileSystem fileSystem = new MockFileSystem(new Dictionary<string, MockFileData>
            {
                { @"c:\myfile.txt", new MockFileData("Testing is awesome.") }
            });
            var component = new ComponentTestable(fileSystem);

            // Act
            Action act = () => component.Validate();

            // Assert
            act.Should().NotThrow();
        }
    }
}

테스트 실행 결과

  • 이처럼, IFileSystem와 MockFileSystem 클래스등을 이용하여 단위 테스트를 진행해 보았습니다.
  • 파일의 내용이 Testing is awesome. 가 아니면 에러가 발생하고 그렇지 않으면 정상동작하는 것을 테스트를 통해 확인할 수 있습니다.

728x90

이 글을 공유하기

댓글

Designed by JB FACTORY