Computer >> 컴퓨터 >  >> 프로그래밍 >> C#

C# 단위 테스트에서 예외를 검증하는 두 가지 방법

단위 테스트(Unit Test)를 작성할 때 메서드가 의도한 대로 예외를 던지는지 검증해야 하는 경우가 자주 있습니다. C#의 MSTest 프레임워크에서는 예외를 확인할 수 있는 방법이 크게 두 가지 있습니다.

  • Assert.ThrowsException 사용
  • [ExpectedException] 특성(Attribute) 사용

테스트 대상 코드 예제

예외를 던지는 StringAppend 메서드를 테스트한다고 가정해 보겠습니다.

using System;
namespace DemoApplication {
    public class Program {
        static void Main(string[] args) {
        }
        public string StringAppend(string firstName, string lastName) {
            throw new Exception("Test Exception");
        }
    }
}

위의 StringAppend 메서드는 호출될 때마다 항상 예외를 발생시키므로, 이 동작이 올바르게 수행되는지 단위 테스트로 검증할 수 있습니다.

방법 1: Assert.ThrowsException 사용

using System;
using DemoApplication;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace DemoUnitTest {
    [TestClass]
    public class DemoUnitTest {
        [TestMethod]
        public void DemoMethod() {
            Program program = new Program();
            var ex = Assert.ThrowsException<Exception>(() => program.StringAppend("Michael", "Jackson"));
            Assert.AreSame(ex.Message, "Test Exception");
        }
    }
}

이 방식에서는 람다 식으로 감싼 메서드 호출을 Assert.ThrowsException<T>에 전달합니다. 지정한 타입(Exception)의 예외가 발생하면 해당 예외 객체가 반환되며, 이후 Assert.AreSame을 통해 예외 메시지까지 추가로 검증할 수 있습니다.

이 방법의 장점은 예외의 타입뿐만 아니라 메시지 등 세부 정보까지 정밀하게 검증할 수 있다는 점입니다. 따라서 위 테스트 케이스는 통과하게 됩니다.

방법 2: ExpectedException 특성 사용

using System;
using DemoApplication;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace DemoUnitTest {
    [TestClass]
    public class DemoUnitTest {
        [TestMethod]
        [ExpectedException(typeof(Exception), "Test Exception")]
        public void DemoMethod() {
            Program program = new Program();
            program.StringAppend("Michael", "Jackson");
        }
    }
}

이 방식은 테스트 메서드에 [ExpectedException] 특성을 붙이고 기대하는 예외의 타입을 지정합니다. 테스트 실행 중 해당 타입의 예외가 발생하면 테스트가 성공하고, 예외가 발생하지 않으면 실패합니다.

StringAppend 메서드가 [ExpectedException(typeof(Exception), "Test Exception")]에 명시된 것과 동일한 타입의 예외를 던지기 때문에, 이 테스트 케이스 역시 통과합니다.

두 방법의 비교 및 권장 사항

Assert.ThrowsException은 예외 객체를 직접 받아서 메시지나 내부 속성을 검증할 수 있어 더 정교한 테스트가 가능합니다. 반면 [ExpectedException] 특성은 코드가 간결하지만, 예외가 발생한 위치를 정확히 특정하기 어렵고 세부 검증이 제한적입니다.

따라서 일반적으로는 예외 메시지까지 확인할 수 있는 Assert.ThrowsException 방식을 사용하는 것이 더 권장됩니다.