2011-05-06 4 views
1

이벤트 구동 비동기 패턴을 통해 비동기 작업을 제공하는 서비스가 있습니다.Moq을 사용하여 이벤트 조롱 (이벤트 기반 비동기 패턴) - UT에서 이벤트에 어떻게 반응합니까?

public interface IService 
{ 
    void DoAsync(int param); 
    event DoCompleted; 
} 

는 기본적으로 CALC 완료 소비자에게 알려야합니다 foo.CalculateAsyc CalculationComplete를 호출 한 후 IService 서비스 개체

public class Foo 
{ 
    private IService _service; 
    public EventHandler CalculationComplete; 
    public void Foo(IService service) {_service = service}; 
    public int Calculated; 
    public void CalculateAsync(int param) 
    { 
    //Invoke _service.DoAsync(param) 
    //(...) 
    } 
} 

에 따라 다른 클래스가있다.

질문은 어떻게 단위 테스트 Foo 때 IService 모의? 나는 Moq을 사용하고있다. 보다 구체적으로 unittest가 CalculationComplete 이벤트를 기다리고 그에 따라 반응하는 방법은 무엇입니까?

답변

6

당신이 여기에서 시험하려고하는 것을 알기가 어렵 기 때문에 100 % 정확한 표본을 줄 수는 없습니다. 샘플 코드가 꽤 부족한 것처럼 보입니다. 누락 된 부분을 채웠지 만, 더 많은 질문이 있습니다.

어쨌든 이벤트 대기를 위해 사용하는 방법은 세마포어입니다. 이와 같은 간단한 경우에 AutoResetEvent를 사용하고 싶습니다.

public class Foo 
{ 
    private IService _service; 
    public EventHandler CalculationComplete; 
    public Foo(IService service) 
    { 
    _service = service; 
    _service.DoCompleted += (o,e) => 
    { 
      Calculated = e.Result; 
     if(CalculationComplete != null) { CalculationComplete(this, new EventArgs()); } 
    }; 
    } 
    public int Calculated; 
    public void CalculateAsync(int param) 
    { 
    _service.DoAsync(param); 
    } 
} 


public interface IService 
{ 
    void DoAsync(int param); 
    event EventHandler<DoResultEventArgs> DoCompleted; 
} 

public class DoResultEventArgs : EventArgs 
{ 
    public int Result { get; set; } 
} 

[TestMethod] 
public void CalculateAsync_CallsService_CalculatedIsPopulated() 
{ 
    //Arrange 
    Mock<IService> sMock = new Mock<IService>(); 
    sMock.Setup(s => s.DoAsync(It.IsAny<int>())) 
      .Raises(s => s.DoCompleted += null, new DoResultEventArgs() { Result = 324 }); 

    Foo foo = new Foo(sMock.Object); 

    AutoResetEvent waitHandle = new AutoResetEvent(false); 
    foo.CalculationComplete += (o,e) => waitHandle.Set(); 

    //Act 
    foo.CalculateAsync(12); 
    waitHandle.WaitOne(); 

    //Assert 
    Assert.IsEqual(foo.Calculated, 324); 
} 

더 자세한 정보가 없으면 내가 할 수있는 최선입니다. 네가 찾고있는 것이 었길 바란다.

+0

감사합니다. – Idan

관련 문제