Swift:使用NSNotificationCenter测试

问题描述:

我试图通过NSNotificationCenter作为应用程序接口发送消息来测试我的应用程序。Swift:使用NSNotificationCenter测试

问题从TestCase类发布。相同的代码适用于在应用程序内发布,但会导致应用程序崩溃,如果从单元测试发布。

为了测试这种情况,我做了一个简单的SingleWindow应用程序。 添加这个消息类的消息传递通过postNotification的USERINFO参数:

class Message { 
    var text:String = "Hi" 
} 

添加MessageHandler的上ViewControler,这样

import UIKit 

class ViewController: UIViewController { 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 
     NSNotificationCenter.defaultCenter().addObserver(self, selector:"messageHandler:", name:"WhatEverMessage", object:nil) 

     //Send message to be catched on MessageHandler func. 
     var userInfo = ["Message": Message()]; 
     NSNotificationCenter.defaultCenter().postNotificationName("WhatEverMessage",object:self, userInfo:userInfo); 
    } 

    override func didReceiveMemoryWarning() { 
     super.didReceiveMemoryWarning() 
     // Dispose of any resources that can be recreated. 
    } 

    func messageHandler(notification:NSNotification){ 

     let message = notification.userInfo!["Message"] as Message 
     println((message as Message).text) 

    } 
} 

当应用程序运行时,viewDidLoad方法发送消息本身,在消息处理器中成功解包

当我尝试通过从TestCase发送另一个消息来测试行为时,应用程序崩溃。发布的代码是完全一样的:

func testExample() { 
    var userInfo = ["Message": Message()]; 
    NSNotificationCenter.defaultCenter().postNotificationName("WhatEverMessage",object:self, userInfo:userInfo); 
} 

当我运行测试,我得到上发布消息的EXC_BREAKPOINT例外,但没有断点设置的项目,然后我得到一个EXC_BAD_ACCESS展开的消息的MessageHandler。

我认为问题是从测试用例发布时,但没有线索。所有编译和链接设置都是此测试项目的默认设置。

已经尝试了很多东西,比如从NSObject派生消息和其他事情的感觉较差。卡在这里。

+0

它看起来并不像你消除对DEINIT观察者。如果以前的测试已经创建并销毁了视图控制器的一个实例,那么dealloc的视图控制器仍然会观察通知。发生了什么事情? – ryanipete 2014-10-05 18:12:31

+0

不,它只有一个测试。 打印收到的消息,我注意到命名空间是错误的。它打印“可选('TargetAppTest'.Message)”并且应该是'TargetApp.Message'。无论如何要从测试代码实例化一个TargetApp.Message? – ByteArtisan 2014-10-05 21:48:03

+0

你在哪里定义Message类?或者,你如何在应用程序目标和测试目标之间共享Message类? – ryanipete 2014-10-06 05:36:40

问题是使用Message类的方式。 Message类被设置为测试目标的一部分。这样,当编译目标时,它会创建一个新的Message类。因为当messageHandler尝试将对象转换为Message类时,它会失败,因为对象具有Message目标类。

要在测试功能上使用Message对象,应将Message类从目标成员中移除并导入。

这里的代码更改:

public class Message { 
    public init(){ //Initializer must be declared to make it public 
    } 
    public var text:String = "Hi" 
} 

在测试方面:

import XCTest 
import MyApp 

class MyAppTests: XCTestCase { 

    ... 

    func testExample() { 
     var userInfo = ["Message": MyApp.Message()]; //Specify namespace MyApp 
     NSNotificationCenter.defaultCenter().postNotificationName("WhatEverMessage",object:self, userInfo:userInfo); 
    } 
}