2010-12-13 4 views
12

몇 가지 예외가 발생하는 한 어떤 예외가 발생하는지 신경 쓰지 않는 경우가 있습니다. 정확히 (파생 클래스 그렇게하지 인스턴스) Exception의 인스턴스가 발생하지 않는 한 불행하게도, xUnit.net에서 예외 무시하기

Assert.Throws<Exception>(someDelegate); 

는 전달하지 않습니다. 나는

Exception exception = Record.Exception(someDelegate); 
Assert.NotNull(exception); 

으로 내가 원하는 동작을 얻을 수 있습니다 알고 있지만 잘 읽지 않습니다. xUnit에서 내가 원하는 행동이있는 뭔가가 빠졌습니까? 여기에 문서 당

[Fact] 
public void Throws_exception_and_passes() { 
    Exception exception = Record.Exception(
     () => { throw new InvalidOperationException(); } 
    ); 
    Assert.NotNull(exception); 
} 

[Fact] 
public void Throws_exception_and_fails() { 
    Assert.Throws<Exception>(
     () => { throw new InvalidOperationException(); } 
    ); 
} 

답변

6

:

http://xunit.codeplex.com/wikipage?title=HowToUse&referringTitle=Home

당신이 던져 질 할 예외의 유형을 지정해야합니다 여기에 내가 무엇을 의미하는지 나타내는 두 개의 테스트입니다. 일반적으로 이는 좋은 습관입니다. 어떤 시나리오에서 어떤 유형의 예외가 발생하는지 예측할 수 있어야합니다. 방법과 테스트 모두를 예측할 수 있도록 디자인 할 수 있어야합니다.

시도해 보는 것이 좋지만 디자인을 조금 변경해야합니다. 당신이 원하는 경우

+0

텍스트와 완전히 일치합니다. 그저 [@Jon Hanna 'answer] (http://stackoverflow.com/a/32468935/11635)에 OP의 원하는 동작 인 –

+0

링크가 깨졌습니다. 이제 내장 된'ThrowsAny'에 대해 자세히 설명하고 싶습니다. xUnit이 github으로 이동했습니다. – mortb

2

xUnit의 당신의 방법에 참을 것이다 Custom Assertion 자신의 뭔가 같은 :

public static bool Throws<T>(this Action action, bool discardExceptions = false) 
    where T : Exception 
{ 
    try 
    { 
     action.Invoke(); 
    } 
    catch (T) 
    { 
     return true; 
    } 
    catch (Exception) 
    { 
     if (discardExceptions) 
     { 
      return false; 
     } 
     throw; 
    } 
    return false; 
} 

또는 : Assert.Throws<T>하지 않는 경우 확인했듯이

public static bool Throws(this Action action) 
{ 
    try 
    { 
     action.Invoke(); 
    } 
    catch (Exception) 
    { 
     return true; 
    } 
    return false; 
} 
+0

참고 : xUnits 내부 Assert-Exceptions는 내부 예외를 다시 발생시키는 캐치를 추가하여 필터링하지 않아야합니다. – k3b

+0

감사 k3b. 또한 행동을 다른 곳에서 부작용이 생기면 상황이 더러워지기 때문에 신중하게 사용하십시오. xUnit이 비슷한 방법을 사용하는지는 모르겠지만 쉽게 확인할 수있을 것입니다. – Nobody

2

계산서에 맞춰서 xUnit에 남아있는 유일한 OOTB 일은 Record.Exception을 사용하고 있습니다. 꽤 없습니다 - 당신이 발견 한 것처럼

는 '어설을하는 주요 방법은 anything`이 그것을

Assert.NotNull(Record.Exception(lambda)) 

봐하는 것입니다 발생합니다. 이것은 의도적으로 설계된 것입니다. 사고로 인해 xUnit.net에는 매우 적은 것들이 있습니다 (신중하게 고려한 디자인과는 대조적으로).

Record.Exception은 이유 때문에 결과를 반환합니다 (그리고 F #을 사용하는 경우 값을 제거하려면 |> ignore). 언제든지 Assert에 예외의 성격에 대한 내용이 있어야합니다. 코드에서 실제 문제가 우연히 무시되지 않도록 시간에 따라 코드를 변경하면이 모든 테스트 작업의 이유가됩니다. 첫 번째 장소는입니다. 아마도 그가 보면

var exception = Record.Exception(sut.Something); 
Assert.True(typeof(SomeException).IsAssignableFrom(exception)); 

의 형태를 취할 수도, 그것은 Assert.NotNull()이 더 안전하지만, 여전히 느낌이 좋지 않습니다. GOOS, 에서 논의 된 바와 같이 테스트를 듣는 시간입니다. (독창적 인 테스트 프레임 워크의 경우 테스트 프레임 워크).


질문에서 가장 큰 문제는 실제 테스트에서 실제 예에서, 사용자의 인터페이스를 명확하게하거나 다른 방법으로 당신의 기대를 표현하는 방법이 항상 있다는 것을 그러나, 그래서 진짜 대답은 Mu입니다.

1

난 그냥 여기 xUnit.net source에보고 된이 범인입니다 :

if(!exceptionType.Equals(exception.GetType())) 

에 :

if(!exception.GetType().IsAssignableTo(exceptionType)) 
이 변경이 적용된 경우 문제가 해결 될지

private static Exception Throws(Type exceptionType, Exception exception) 
{ 
    Guard.ArgumentNotNull("exceptionType", exceptionType); 

    if (exception == null) 
     throw new ThrowsException(exceptionType); 

    if (!exceptionType.Equals(exception.GetType())) 
     throw new ThrowsException(exceptionType, exception); 

    return exception; 
} 

패치를 제출할 수 있습니까?

+0

내 답변에 언급했듯이, 여기에는 '범인'이 없습니다. 우연히이 방법으로 쓰여졌을 가능성은 전혀 없습니다. 즉, 궁극적으로 예외가 인터페이스의 일부인 경우에 어떤 예외가 발생하는지 테스트가 구체적이어야한다는 것입니다. @ rmx의 대답은 OP가 기대하는 것을 작성하는 방법을 설명하고 http://stackoverflow.com/a/32468935/11635는 현재 내장 된 'ThrowsAny'를 설명합니다 –

4

이 질문 시점에는 존재하지 않았지만 이제 Exception (예외적으로 예외)에서 파생 된 모든 예외를 테스트하기 위해 Assert.ThrowsAny<Exception>을 사용할 수 있습니다. Assert.ThrowsAny<ArgumentException>과 같은 변형을 테스트하여 에서 파생 된 예외입니다.

+0

이 질문에 대한 답변은 *지만 대답은 [poindexter] (http://stackoverflow.com/a/4451224/2874896)에서 테스트를 실제로 작성하기 전에 고려해야 할 가치가 있습니다. –

0
public static void SuppressException<TSut>(this TSut value, Action<TSut> action) where TSut : class 
    { 
     try 
     { 
      action.Invoke(value); 
     } 
     catch (Exception) 
     { 
      //do nothing 
     } 
    } 
관련 문제