2012-09-03 4 views
1

두 개의 WCF 서비스를 여는 Windows 서비스가 있습니다. 나는 단위 테스트 OnStart()를 원하고 service1.Open()과 service2.Open()이 호출되고 있음을 주장한다. ONSTART()는 다음과 같습니다내 단위 테스트에서 ServiceHost에 Open()이 호출되었음을 어떻게 확인할 수 있습니까?

protected override void OnStart(string[] args) 
{ 
    // host WCF services    
    _service1.Open();   
    _service2.Open(); 
} 

내가 같은 생성자 오버로드에 서비스를 주입 해요 : 나는이 같은 ServiceHostBase의 스텁을 생성하는 RhinoMocks를 사용하고

public WinService(ServiceHostBase service1, 
            ServiceHostBase service2) 
{ 
    _service1 = service1; 
    _service2 = service2; 
    InitializeComponent(); 
} 

:

[TestMethod()] 
public void WinServiceOnStartCallsDependenciesAsExpected() 
{ 
    ServiceHostBase service1 = MockRepository.GenerateStub<ServiceHostBase>(); 
    ServiceHostBase service2 = MockRepository.GenerateStub<ServiceHostBase>(); 
    WinService target = new WinService(service1, service2); 
    WinService_Accessor privateTarget = new WinService_Accessor(new PrivateObject(target));  
    privateTarget.OnStart(null); 

내 테스트에서 OnStart()를 호출하면 service1.Open()을 호출 할 때 null 참조 예외가 발생합니다. 나는 service1이 그 시점에서 조롱 된 객체이며 null을 던지는 Open()임을 확인했습니다. Open() 실제로 System.ServiceModel.Channels.CommunicationObject 메서드를 알고 Stubbing 또는 Mocking뿐만 아니라,하지만 여전히 개체 참조 오류가 발생합니다. 그것은 가상 메소드가 아니기 때문에 조롱 된 버전에 의해 오버라이드되지는 않을 것이라고 생각할 것입니다. 그러나 Expectation reportservice.Stub(r => r.Open())을 설정하려고하면 기본 타임 아웃이 아닌 실제 예외를 실행하는 것처럼 다른 예외가 생깁니다. CommunicationObject Open() 메소드. null 참조를 던지고있는 RhinoMocky입니다.

이 모든 것을 말하자면, 저는 UnitHP에서 ServiceHost에서 Open()이 호출되고 있음을 확인하는 방법에 대한 도움을 찾고 있습니다. =]

답변

1

ServiceHostBase.Open 후드 아래 CommunicationObject.Open가 호출됩니다. 구현의 일부로 객체의 상태 확인, 다른 객체 만들기, 메서드, 속성 등을 호출하는 것과 같은 여러 가지 작업을 수행합니다. 가상이 아니기 때문에 Rhino는 기본 클래스 구현을 호출합니다. 일부 유형/방법이 간단 코뿔소에 의해 unmockable 수 있습니다 (

은 아마 조롱과 CommunicationObject 종속성 스텁을 많이해야합니다, 그것이 작동되도록하려면 아직도 당신이 성공하는 것입니다 여부를 확신 할 수 또는하지 않을 것이다 정적, 봉인 또는 기타 비 가상이라고 생각할 때). 따라서 다음 중 하나를 선택해야합니다.

  1. 통합 테스트에는 이러한 종류의 테스트를 남겨 두어야합니다. 그러면 .Open이 최종 사용자 환경에서 테스트 될 것입니다.
  2. wrapper 주위에 ServiceHostBase을 도입하고 인터페이스별로 종속성으로 전달하십시오. 이 추가 작업 (새 인터페이스와 간단한 래퍼 클래스)를 포함,하지만 당신은 당신이

래퍼를 추가하는 경우에만 기본적으로 래퍼 클래스 'Open 방법에 (더 문제를 위임 할 것이라는 점을 명심 원을 정확하게 수행 할 수 있습니다 ServiceHostBase.Open에 전화 할 것입니다 - 당신은 그것도 단위 테스트를해야합니까?). 반면에 통합 테스트는 단위 테스트만큼 빨리 문제를 포착하지 않을 수도 있습니다. 얼마나 중요하다고 생각하는지에 따라 OnOpen을 선택하면 어떤 방식 으로든 판단력이 향상됩니다.

+0

그래, 나는 래퍼 접근법에 대해 논쟁을 벌 였지만, 우리는 단지 그 사실을 밝혀야 할 것이라고 생각한다. Open() 호출은 절대로 조건부 적이 지 않으므로 위험성으로 인해 그만한 가치가있는 추가적인 복잡성이없는 것처럼 보입니다. 놀랍게도 놀라운 일이 발생하지 않는다면 나는 이것을 답으로 표시 할 것입니다. – sonicblis