2009-06-18 5 views
1

특정 ErrorCode에 대해서만 ManagementException 예외를 처리하고 이에 대한 단위 테스트를 작성하는 데 문제가 있습니다. 그것은 다음과 같이되도록 일반적으로, 내가 테스트를 작성합니다ManagementException의 ErrorCode를 설정하는 방법은 무엇입니까?

Searcher search = MockRepository.GenerateMock<Searcher>(); 
// wrapper for ManagementObjectSearcher 

... 

search.Expect(s => s.Get()).Throw(new ManagementException()); 

... 

그러나,이 내가 특별히 원하는 일에 ErrorCode가 설정되지 않습니다가, 참으로 ManagementException 생성자를 가지고 있지 않는 이 값을 설정합니다.

어떻게이 작업을 수행 할 수 있습니까?

(내 조롱 프레임 워크로 RhinoMocks를 사용하고 있지만 여기는 프레임 워크에 독립적이라고 가정하고 있는데, 여기서는 특정 ErrorCode 값을 가진 ManagementException을 만드는 방법을 알아야합니다. 또한 일부 참조를 발견했습니다. 온라인으로 System.Management.ManagementException.ThrowWithExtendedInfo(ManagementStatus errorCode) 방법으로 전송하지만 공개적으로 액세스 할 수있는 것은 아닙니다.

답변

3

이 장애물을 극복하기위한 최소한의 노력은 필요한 오류 코드의 반사를 해킹 슬롯에 적용하는 정적 도우미/유틸리티 방법입니다.가장 우수한 Reflector를 사용하면 ManagementException에 정의 된 내부 cterors를 통해서만 설정되는 private "errorCode"필드가 있음을 알 수 있습니다. 그래서 :)

public static class EncapsulationBreaker 
    { 
     public static ManagementException GetManagementExceptionWithSpecificErrorCode(ManagementStatus statusToBeStuffed) 
     { 
     var exception = new ManagementException(); 
     var fieldInfo = exception.GetType().GetField("errorCode", 
      BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetField | BindingFlags.DeclaredOnly); 
     fieldInfo.SetValue(exception, statusToBeStuffed); 
     return exception; 
     } 
    } 

그것이 내가 일반적으로 테스트에 반사에 싫은 내색을

[Test] 
     public void TestGetExceptionWithSpecifiedErrorCode() 
     { 
     var e = EncapsulationBreaker.GetManagementExceptionWithSpecificErrorCode(ManagementStatus.BufferTooSmall); 
     Assert.AreEqual(ManagementStatus.BufferTooSmall, e.ErrorCode); 
     } 

있지만 작동하는지 검증, 이것은이/도움이 필요한 드문 경우 중 하나입니다.
HTH

+0

내가 필요한 것. 감사! – jpoh

1

ManagementException에서 클래스를 파생시키고 사용자 고유의 오류 코드 구현을 숨 깁니다. 너의 모의 수업을이 수업 시간에 가져 가라.

0

하위 클래스는 ErrorCode 게터를 덮어 씁니다 (정상적인 보호 수준으로 인해 중지되는 경우 내성 검사가 더 가까워 질 수 있습니다). ManagementException을 처리하지만 특정 하위 클래스에 대해 전혀 들어 본 적이없는 코드는 서브 클래스를 "마치 마치"테스트 목적으로 시뮬레이션하려고 시도한 ManagementException이었습니다.

편집 : 그것은 생각할 수 있다는 ErrorCode 단지 나는 그들이 이런 식으로 테스트를 중지 할 수 있도록 강성 언어 싫어하지만 ;-) 그들이 존재 부정 할 수 없다 (재정의 할 수 없습니다. 이 경우, 의존성 주입은 여전히 ​​당신을 구할 수 있습니다 - DI는 테스트를 위해 제가 가장 좋아하는 패턴 중 하나입니다.

DI는 테스트중인 코드를 테스트 가능성을 저해하는 딱딱한 가정에서 분리하는 것을 목적으로합니다. 이는 예외적 인 형태 일지라도 여기에있는 것입니다. 현재 테스트중인 코드는 x.ErrorCode이며 예외 x의 오류 코드를 얻습니다. 아주 잘, 그 대신에해야합니다, getErrorCode(x)getErrorCode은 일반적으로 그냥 대표단입니다 return x.ErrorCode; getErrorCode 대리인에 대한 설정자가 있어야 테스트 목적으로 return 23 (또는 테스트를 위해 시뮬레이트하려는 모든 오류 코드 값)을 수행하는 대리인으로 변경할 수 있습니다.

자세한 내용은 다를 수 있지만 종속성 주입은 시스템에서 (또는 직접 수정할 수없는 다른 라이브러리 &c) 불가피하게 얻을 수있는 개체의 과도한 강성을 보완하는 데 도움이 될 수 있습니다 예.

+0

내가 ManagementException을 모의한다면 RhinoMocks가 그랬습니다. 그러나 ErrorCode는 override-ble 특성이 아닙니다. 내성으로 당신이 의미하는 것을 자세히 설명해 주시겠습니까? – jpoh

+0

네이티브 .NET의 경우 http://msdn.microsoft.com/en-us/library/system.reflection.aspx입니다. 그러나이 방법으로 재정의 할 수없는 속성이있는 경우 종속성 주입이 마지막입니다. 최선의 희망 - 설명해 드리겠습니다. –

0

매우 간단하고 작은 메서드 나 클래스가있어 해당 예외를 catch하고 오류 코드를 가져온 다음 작업을 수행하는 실제 클래스로 전달합니다. 테스트 할 때 해당 코드를 실제 클래스에 직접 전달하여 해당 오류 코드를받을 때 전달할 코드를 대체하십시오.

가장 확실한 방법은 예외를 서브 클래 싱하는 것이지만, 작동하지 않으면 코드를 포착하고 즉시 코드를 노출 할 수있는 자신의 예외를 던집니다. 다른 옵션이 될 수 있습니다.