2013-04-12 14 views
0

我正在写一个使用MonoTouch的iOS应用程序,这个应用程序在很多不同的屏幕上输入了很多信息。信息A,B和C可能会在屏幕1上输入,但我需要在屏幕3上显示信息B以及信息X,Y,Z等的输入。用户可以从屏幕1跳到屏幕7,然后回到屏幕3.如何对依赖NSNotificationCenter的单元/集成测试类(在MonoTouch中)进行测试?

所以,我创建了一个静态类来接收所有信息(通过NSNotifications)并缓存它。它还监听来自各种屏幕的信息请求(通过NSNotifications),从缓存中打包相关信息(以私有静态方法),并发出另一个通知作为响应。此类应始终具有最新的信息,因此无论用户跳转到哪个屏幕都应如此。

public static class InformationFlowController 
{ 
    static List<NSObject> _observers; 
    static Dictionary<SomeEnum, Object> _data; 

    static InformationFlowController() 
    { 
     _observers = new List<NSObject>(); 
     _data = new Dictionary<SomeEnum, Object>(); 

     _observers.Add(NSNotificationCenter.DefaultCenter.AddObserver(Notifications.PayloadA, HandlePayloadA)); 
     ... 
     _observers.Add(NSNotificationCenter.DefaultCenter.AddObserver(Notifications.RequestA, HandleRequestA)); 
    } 

    // receive information A 
    static void HandlePayloadA(NSNotification ntf) 
    { 
     var infoA = (InfoA)ntf.Object; 
     if (A == null) { /* throw an exception */ } 

     if (_data.ContainsKey(EnumA)) 
     { 
      _data.Remove(EnumA); 
     } 

     _data.Add(EnumA, infoA); 
    } 

    // receive request for info A 
    static void HandleRequestA(NSNotification ntf) 
    { 
     InfoA info = null; 

     if (_data.ContainsKey(EnumA)) 
     { 
      info = _data.GetValue(EnumA); 
     } 

     // its up to the receiver what it wants to do if it gets null 
     NSNotificationCenter.DefaultCenter.PostNotificationName(Notifications.ResponseA, info); 
    } 
} 

这一切工作正常。

我的问题是我该如何进行单元/集成测试呢? 由于app/policy/yadda-yadda的性质,我必须拥有〜100%的代码覆盖率。这是我尝试过的以及我遇到的情况。

我有尝试写这样一个集成测试是确保如果我做一个信息的请求,我得到的信息A.响应

[Test] 
public void HandleRequestForATest() 
{ 
    // setup the data in the IFC here 

    NSNotificationCenter.DefaultCenter.AddObserver(Notifications.ResponseA, delegate(NSNotification ntf) 
    { 
     var info = ntf.Object as InfoA; 
     Assert.IsNotNull(info, "Info is null!"); 
     // some other asserts to check the data within info 
    } 

    NSNotificationCenter.DefaultCenter.PostNotificationName(Notifications.RequestA, null);   
} 

测试通过用0断言的问题。我在var info = ntf.Object as InfoA;上放了一个断点,它永远不会被感动。我想也许它在得到响应之前获得GC'd,但我在IFC.HandleRequestA方法中放置了一个断点,它永远不会被调用。通过检查,我可以看到通知正在向DefaultCenter注册,但他们似乎没有被解雇。

除此之外,如何测试以确保在一定的时间内收到通知,如果不是,测试失败?我尝试添加一个类变量:

bool assertsCompleted = false; 

和修改测试:

[Test] 
public void HandleRequestForATest() 
{ 
    // setup the data in the IFC here 

    NSNotificationCenter.DefaultCenter.AddObserver(Notifications.ResponseA, delegate(NSNotification ntf) 
    { 
     var info = ntf.Object as InfoA; 
     Assert.IsNotNull(info, "Info is null!"); 
     // some other asserts to check the data within info 
     assertsCompleted = true; 
    } 

    NSNotificationCenter.DefaultCenter.PostNotificationName(Notifications.RequestA, null);   

    NSTimer.CreateTimer(2, delegate 
    { 
     if (!assertsCompleted) 
     { 
      Assert.IsTrue(false, "Notification not received or Asserts not complete!"); 
     } 
    } 
} 

我把一个断点if (!assertsCompleted)并没有得到任何打击。

请帮忙! :)

EDIT2 我从静态到非静态(以及方法)改变了IFC类和固定与不被调用的处理程序的问题。这意味着我必须在AppDelegate和TestFixtureSetUp中实例化它,但我认为我们可以忍受这一点。 /EDIT2

+0

(http://stackoverflow.com/q/ 4373079/639445) – miek

回答

2

你可以尝试这样的事:[已编辑成另外一个问题的问题的另一部分是在这里]

[Test] 
public void HandleRequestForATest() 
{ 
    // setup the data in the IFC here 

    var resetEvent = new ManualResetEvent(false); 
    InfoA info = null; 

    var observer = NSNotificationCenter.DefaultCenter.AddObserver(Notifications.ResponseA, delegate(NSNotification ntf) 
    { 
     info = ntf.Object as InfoA; 
     resetEvent.Set(); 
    } 

    NSNotificationCenter.DefaultCenter.PostNotificationName(Notifications.RequestA, null);   

    Assert.IsTrue(resetEvent.WaitOne(250), "Reset event timed out!"); 
    Assert.IsNotNull(info, "Info is null!"); 
    // some other asserts to check the data within info 

    //Make sure you do this! I'd put in try-finally block 
    NSNotificationCenter.DefaultCenter.RemoveObserver(observer); 
} 
+0

我不了解ManualResetEvent。这解决了第二个问题的一部分。 – miek

相关问题