[C#] Assert를 사용하여 예외가 발생했는지 어떻게 확인합니까?

Assert예외가 발생했는지 확인 하려면 어떻게해야합니까 (또는 다른 테스트 클래스?)?



답변

“Visual Studio Team Test”의 경우 ExpectedException 특성을 테스트 방법에 적용합니다.

여기 문서의 샘플 : Visual Studio Team Test를 사용한 단위 테스트 연습

[TestMethod]
[ExpectedException(typeof(ArgumentException),
    "A userId of null was inappropriately allowed.")]
public void NullUserIdInConstructor()
{
   LogonInfo logonInfo = new LogonInfo(null, "P@ss0word");
}


답변

일반적으로 테스트 프레임 워크에 이에 대한 답변이 있습니다. 그러나 융통성이 충분하지 않으면 언제든지 다음을 수행 할 수 있습니다.

try {
    somethingThatShouldThrowAnException();
    Assert.Fail(); // If it gets to this line, no exception was thrown
} catch (GoodException) { }

@Jonas가 지적했듯이 이것은 기본 예외를 잡기 위해 작동하지 않습니다.

try {
    somethingThatShouldThrowAnException();
    Assert.Fail(); // raises AssertionException
} catch (Exception) {
    // Catches the assertion exception, and the test passes
}

Exception을 반드시 잡아야하는 경우 Assert.Fail ()을 다시 발생시켜야합니다. 그러나 실제로, 이것은 당신이 이것을 손으로 쓰면 안된다는 신호입니다. 테스트 프레임 워크에서 옵션을 확인하거나 테스트를 위해 더 의미있는 예외를 던질 수 있는지 확인하십시오.

catch (AssertionException) { throw; }

어떤 종류의 예외를 잡아야 하는지를 포함하여 원하는 방식으로이 방법을 적용 할 수 있어야합니다. 특정 유형 만 예상하면 다음 catch과 같이 블록을 마무리하십시오 .

} catch (GoodException) {
} catch (Exception) {
    // not the right kind of exception
    Assert.Fail();
}


답변

이것을 구현하기 위해 내가 선호하는 방법은 Throws라는 메소드를 작성하고 다른 Assert 메소드와 마찬가지로 사용하는 것입니다. 불행히도 .NET에서는 정적 확장 메서드를 작성할 수 없으므로이 메서드는 마치 Assert 클래스의 빌드에 속하는 것처럼 사용할 수 없습니다. MyAssert 또는 이와 유사한 다른 것을 만드십시오. 수업은 다음과 같습니다.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace YourProject.Tests
{
    public static class MyAssert
    {
        public static void Throws<T>( Action func ) where T : Exception
        {
            var exceptionThrown = false;
            try
            {
                func.Invoke();
            }
            catch ( T )
            {
                exceptionThrown = true;
            }

            if ( !exceptionThrown )
            {
                throw new AssertFailedException(
                    String.Format("An exception of type {0} was expected, but not thrown", typeof(T))
                    );
            }
        }
    }
}

즉, 단위 테스트는 다음과 같습니다.

[TestMethod()]
public void ExceptionTest()
{
    String testStr = null;
    MyAssert.Throws<NullReferenceException>(() => testStr.ToUpper());
}

나머지 단위 테스트 구문과 훨씬 비슷하게 보이고 동작합니다.


답변

NUNIT을 사용하면 다음과 같이 할 수 있습니다.

Assert.Throws<ExpectedException>(() => methodToTest());

추가로 확인하기 위해 발생 된 예외를 저장할 수도 있습니다.

ExpectedException ex = Assert.Throws<ExpectedException>(() => methodToTest());
Assert.AreEqual( "Expected message text.", ex.Message );
Assert.AreEqual( 5, ex.SomeNumber);

참조 : http://nunit.org/docs/2.5/exceptionAsserts.html


답변

원래 ExpectedException속성 이 없었던 MSTest를 사용하는 경우 다음을 수행 할 수 있습니다.

try
{
    SomeExceptionThrowingMethod()
    Assert.Fail("no exception thrown");
}
catch (Exception ex)
{
    Assert.IsTrue(ex is SpecificExceptionType);
}


답변

다음과 같이 ExpectedException 사용에주의하십시오.

http://geekswithblogs.net/sdorman/archive/2009/01/17/unit-testing-and-expected-exceptions.aspx

그리고 여기:

http://xunit.github.io/docs/comparisons.html

예외를 테스트해야하는 경우 방법에 대한 찌푸림이 적습니다. try {act / fail} catch {assert} 메소드를 사용하면 ExpectedException 이외의 예외 테스트를 직접 지원하지 않는 프레임 워크에 유용 할 수 있습니다.

더 나은 대안은 xUnit.NET을 사용하는 것입니다. xUnit.NET은 다른 모든 실수에서 배워 개선 된 매우 현대적이고 미래 지향적이며 확장 가능한 단위 테스트 프레임 워크입니다. 이러한 개선 사항 중 하나는 Assert.Throws이며 예외를 주장하는 데 훨씬 더 좋은 구문을 제공합니다.

github에서 xUnit.NET을 찾을 수 있습니다 : http://xunit.github.io/


답변

MSTest (v2)에는 이제 다음과 같이 사용할 수있는 Assert.ThrowsException 함수가 있습니다.

Assert.ThrowsException<System.FormatException>(() =>
            {
                Story actual = PersonalSite.Services.Content.ExtractHeader(String.Empty);
            }); 

너겟으로 설치할 수 있습니다 : Install-Package MSTest.TestFramework