2012-02-27 4 views
1

안녕과 이벤트 subscribtion 누군가가 내 질문에 대한 답을 알고 궁금 :방법 단위 테스트가 NUnit과

다음 코드 이 내 질문은 여기

class TheHandler 
{ 
    ... 
    Public EventHandler myRealWorldEvent; 
    ... 


} 

class TheSubscriber 
{ 
    private TheHandler myHandler = new TheHandler(); 

    public subscribeToHandler() 
    { 
     myHandler.myRealWorldEventHandler += OnSomethingHappens; 

    } 

    ... 

    pirvate OnSomeThingHappens() 
    { 
     ... 
    } 
} 
고려 -> 내가 어떻게 테스트 할 수 있습니다 OnSomethingHappens가 myRealWorldEventHandler에 가입했다는 것을 의미합니다 (NUnit 만 해당). 나는 SUT/생산 코드를 변경할 수없고 모의 (Moq/Nmock 등)도 할 수 없다. 누구든지 내 문제에 대한 해결책을 알고 있습니까?

안부,

zhengtonic

+0

'myRealWorldEvent'가 실행될 때'OnSomethingHappens'가 호출되는지 테스트하고 싶습니까? 맞아? –

+0

OnSomethingHappens가 myRealworldEventHandler에 가입했는지 알고 싶습니다. 그러나 그렇습니다 나는 그것에게 시험 결과를 발사해서 좋다. NMock에서 Expect.Once.On (myRealworldEventHandler) .EventAdd (OnSomethingHappens, Is.Anything); – zhengtonic

답변

1

NUnit과 그렇게하지 않습니다 - 일부 개인 핸들러가 일부 개인 필드에 가입 여부를 테스트. 개인 물건이 너무 많이 포함되어 있습니다. 그러나, 그것은 당신이 반사에서 약간의 도움으로 할 수없는 것은 아닙니다. 꽤 코드 아니라고 참고 :

var subscriber = new TheSubscriber(); 
var handlerField = typeof(TheSubscriber) 
    .GetFields(BindingFlags.NonPublic | BindingFlags.Instance) 
    // if field with such name is not present, let it fail test 
    .First(f => f.Name == "myHandler"); 

var handlerInstance = handlerField.GetValue(subscriber); 
var someEventField = typeof(TheHandler) 
    .GetFields(BindingFlags.NonPublic | BindingFlags.Instance) 
    .First(f => f.Name == "myRealWorldEvent"); 

var eventInstance = (EventHandler) someEventField.GetValue(handlerInstance); 
var subscribedMethod = eventInstance 
    .GetInvocationList() 
    .FirstOrDefault(d => d.Method.Name == "OnSomethingHappens"); 

Assert.That(subscribedMethod, Is.Not.Null); 

레거시 시스템 테스트를 많이 처리해야하는 경우. (예 : 개인 회원, 정적 멤버 - 무료 프레임 워크가 잘 또는 전혀 처리하지 않는 일) - TypeMock 또는 JustMock과 같은 도구를 살펴 보는 것이 좋습니다.

+0

옙의 레거시 코드 ... 재미있는 시간 ... 팁을위한 thx! – zhengtonic

0

같은 문제가있었습니다. jimmy_keen의 코드가 이전 .NET과 제대로 작동하지 않았습니다.

public static void assertSubscribed<EventHandlerType>(object handler, object subscriber, string eventName = null) { 
    var inappropriate = false; 
    try { 
     if (!typeof (EventHandlerType).IsSubclassOf(typeof (Delegate)) || 
      typeof (EventHandlerType).GetMethod("Invoke").ReturnType != typeof (void)) 
      inappropriate = true; 
    } catch (AmbiguousMatchException) { 
     inappropriate = true; 
    } finally { 
     if (inappropriate) throw new Exception("Inappropriate Delegate: " + typeof (EventHandlerType).Name); 
    } 

    var handlerField = subscriber.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance) 
     .First(h => h.FieldType.IsInstanceOfType(handler)); 

    var handlerInstance = handlerField == null ? null : handlerField.GetValue(subscriber); 
    var eventField = handlerInstance == null ? null : handlerInstance.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance) 
     .First(f => (f.FieldType.IsAssignableFrom(typeof (EventHandlerType)) && 
        (eventName == null || eventName.Equals(f.Name)))); 

    var eventInstance = eventField == null ? null : (Delegate)eventField.GetValue(handlerInstance); 
    var subscribedMethod = eventInstance == null 
     ? null 
     :eventInstance.GetInvocationList().FirstOrDefault(
      d => d.Method.DeclaringType != null && d.Method.DeclaringType.IsInstanceOfType(subscriber)); 

    Assert.That(subscribedMethod, Is.Not.Null); 
} 

"없음"방법 :

public static void assertNotSubscribed<EventHandlerType>(object handler, object subscriber, string eventName = null) { 
    var inappropriate = false; 
    try { 
     if (!typeof (EventHandlerType).IsSubclassOf(typeof (Delegate)) || 
      typeof (EventHandlerType).GetMethod("Invoke").ReturnType != typeof (void)) 
      inappropriate = true; 
    } catch (AmbiguousMatchException) { 
     inappropriate = true; 
    } 
    if (inappropriate) return; 

    var handlerField = subscriber.GetType().GetFields(BindingFlags.NonPublic | BindingFlags.Instance) 
     .First(h => h.FieldType.IsInstanceOfType(handler)); 

    var handlerInstance = handlerField == null ? null : handlerField.GetValue(subscriber); 

    var eventField = handlerInstance == null ? null : handlerInstance.GetType() 
     .GetFields(BindingFlags.NonPublic | BindingFlags.Instance) 
     .First(f => (f.FieldType.IsAssignableFrom(typeof (EventHandlerType)) && 
        (eventName == null || eventName.Equals(f.Name)))); 

    var eventInstance = eventField==null?null:(Delegate) eventField.GetValue(handlerInstance); 
    var subscribedMethod = eventInstance == null 
     ? null 
     : eventInstance.GetInvocationList().FirstOrDefault(
       d => d.Method.DeclaringType != null && d.Method.DeclaringType.IsInstanceOfType(subscriber)); 

    Assert.That(subscribedMethod, Is.Null); 
} 

그리고 호출 :

이 가
assertSubscribed<EventHandler>(handler, subscriber); 
assertNotSubscribed<EventHandler>(handler, subscriber); 
assertSubscribed<EventHandler>(handler, subscriber, "myRealWorldEvent"); 
assertNotSubscribed<EventHandler>(handler, subscriber, "myRealWorldEvent"); 

코드 스타일 대회 귀찮게하지만,하지 마십시오이 방법은 소형 보인다 작성 도우미 방법으로이를 해결 충분히.

관련 문제