2014-10-05 59 views
1

我試圖通過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

回答

0

問題是使用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); 
    } 
}