2009-08-27 9 views
4

공용 인터페이스 만 테스트해야한다는 의견에 따라 개인 절차 테스트를 다루는 경향이 있습니다. 그러나 어제 재미있는 질문이 생겼습니다. 이벤트 처리기를 테스트해야합니까? 내 직감은 논리가 처리기 자체가 호출하는 자체 포함 된 절차에 저장해야한다는 것이지만 주관적이며 테스트를 거치는 공용 절차가 아닌 개인 절차가 될 가능성이 높습니다. 내가 단위 테스트 이벤트 처리기일까요, 만약 그렇다면, 그렇게하는 가장 좋은 방법은 무엇입니까?테스트 이벤트 핸들러를 유니트해야합니까?

답변

0

필자는 이벤트 처리기를 테스트해야한다고 생각합니다. 당신의 라인을 따라 뭔가를하고 정상적인 패턴을 따르는 경우 :

public event EventHandler MyEvent; 
protected void OnMyEvent() 
{ 
    // Raise MyEvent here 
} 
유일한 "테스트"당신이 할 것입니다 이벤트가 있는지 확인하기 때문에 그런 myEvent가 테스트가 효과적으로 OnMyEvent의 시험의 일부입니다

제대로 올랐다.

일반적으로 이벤트를 테스트하는 것은 이벤트를 구독하고 이벤트를 발생시키는 (또는 발생시키지 않아야하는) 작업을한다는 것을 의미합니다.

0

나는 귀하의 질문을 읽고 당신이 처리기의 본문에 대해 물어 본지 여부 또는 처리기 실제로 이벤트를 처리하기 위해 올바르게 바인딩되었는지 여부를 몰랐습니다.

당신이 말했듯이, 처리기의 본문은 이미 테스트 한 다른 메서드를 호출해야합니다 (공개 된 경우).

일반적으로 런타임에 변경하지 않으면 이벤트 처리기의 배선을 단위 테스트하지 않습니다. 개발자/통합 테스트/바인딩 해제 이벤트 처리기를 잡을 가능성이 매우 높습니다. 런타임에는 유선이 아니며 있어야합니다.

2

아무리해도 누군가가 이벤트 처리기를 테스트하는 유닛에 대해 "잘못"하다고 말할 것입니다. 개인적으로 "깨질 수있는 부분을 테스트하라"는 철학과 함께 갈 것입니다.

내가 이벤트 코드를 지속적으로 잘못 본 적이 중요한 것은 뭔가 단위 테스트를 잡을 것이다 -은 "On"으로 메소드는 것입니다 :

if (MyEventHandler != null) 
    MyEventHandler(this, e); 

이것은 경쟁 조건이있다; MyEventHandler는 널 검사 전에 변수에 지정되어야합니다.

두 x 째 일]적인 오류는 "e"이벤트 데이터 매개 변수에 널 (NULL)을 전달하는 사람들입니다. 이것은 테스트 될 수 있습니다.

프레임 워크 디자인 지침 2 판을 소유하지 않은 경우. Cwalina & Abrams, 지금 구입하십시오. 매번 이벤트 코드를 정확하게 작성하는 방법, Dispose Pattern을 올바르게 작성하는 방법 및 기타 여러 가지 사항을 알려줍니다.

+0

정말 당신이 그렇게 말하는 것을 생각 나 갈 그 나는 희망을 갖고 당신이 말한 것에 대해 칭찬할만한 것을 올렸습니다.이 친구를 불러내는데 아주 좋았습니다. 아주 좋아요! –

0

TrueWill의 요점은 다음은 이벤트 및 해당 raise 메소드의 좋은 구현 예입니다. Microsoft의 Button 클래스 인 Click 이벤트입니다. 그들은에서 ...

protected EventHandlerList Events { 
    get { 
     if (events == null) { 
      events = new EventHandlerList(this); 
     } 
     return events; 
    } 
} 

... 

public event EventHandler Click { 
    add { 
     Events.AddHandler(EventClick, value); 
    } 
    remove { 
     Events.RemoveHandler(EventClick, value); 
    } 
} 

이제 실제 인상 방법 OnClick에 대한 주석을 할당을 저장하는 EventHandlerList를 사용하는 것이 첫째 주, 그것은 ... 아마 당신이보고에 사용하는 것보다 훨씬 다르다

protected virtual void OnClick(EventArgs e) { 
    Contract.Requires(e != null); 
    EventHandler handler = (EventHandler)Events[EventClick]; 
    if (handler != null) handler(this, e); 
} 

...라인 Contract.Requires(e != null);에 대해 걱정하지 마십시오. 계약 관리 프레임 워크입니다. 그러나 EventHandlerList에서 가져오고 그 핸들러가 null이 아니면 발사합니다.

여기에 주목할 가치가있는 또 다른 사항은 이벤트를 구현하는 데 거의 동일한 방식으로 구현할 필요가 없을 가능성이 있지만 Microsoft의 프로그래밍 가이드는 실제로이 두 번째 부분에서 경쟁 조건을 호출합니다 TrueWill이 지적한 가이드입니다. 가이드 here을 찾을 수 있습니다. 이것은 실제로 Microsoft의 훌륭한 가이드입니다.

는 지금, 당신의 점에 , 나는 ... 이벤트는 테스트 여기에 내가 과거에 사용했던 메커니즘입니다되어야한다고 생각

private ManualResetEvent _eventRaised = new ManualResetEvent(false); 

[TestMethod] 
public void TestSomething() 
{ 
    _eventRaised.Reset(); 

    // hook up the event to the target being tested 
    // NOW, in the event handler, issue _eventRaised.Set(); 

    // do something to raise the event 

    _eventRaised.WaitOne(); 
} 
관련 문제