2016-10-04 43 views
0

我有一個庫實現自定義UIControl的方法,該方法在調用時會觸發一個.valueChanged事件。我想測試該行爲的方法。如何測試UIControlEvents是否已被觸發

我的自定義控件:

class MyControl: UIControl { 
    func fire() { 
     sendActions(for: .valueChanged) 
    } 
} 

而且測試:

import XCTest 

class ControlEventObserver: NSObject { 
    var expectation: XCTestExpectation! 

    init(expectation anExpectation: XCTestExpectation) { 
     expectation = anExpectation 
    } 

    func observe() { 
     expectation.fulfill() 
    } 
} 

class Tests: XCTestCase { 
    func test() { 
     let myExpectation = expectation(description: "event fired") 
     let observer = ControlEventObserver(expectation: myExpectation) 
     let control = MyControl() 
     control.addTarget(observer, action: #selector(ControlEventObserver.observe), for: .valueChanged) 
     control.fire() 
     waitForExpectations(timeout: 1) { error in 
      XCTAssertNil(error) 
     } 
    } 
} 

的問題是observe方法不會被調用,因此expectation沒有實現。

問題是:我們如何在這種情況下測試UIControlEvents?也許我們需要以某種方式強制runloop?

編輯1: 請注意,由於我正在測試庫,我的測試目標沒有任何主機應用程序。當測試目標具有主機應用程序時,上述測試通過。

+1

這很奇怪我已經在我創建的項目中複製並粘貼了您的代碼,並且期望已全滿,測試成功通過。 – Wilson

+0

剛剛意識到這可能是因爲我正在測試一個庫。當我使用主機應用程序創建另一個測試目標時,上面的測試通過。 @WilsonB​​alderrama –

回答

4

Apple's documentation for UIControl指出:

當特定控制的事件發生時,控件調用任何相關 動作方法的時候了。 通過 當前的UIApplication對象調度操作方法,如果需要,可以在響應器鏈之後找到適當的對象來處理消息。

sendActions(for:)上調用UIControl,控制將調用UIApplicationsendAction(_:to:from:for:)該事件傳遞到準的目標。

由於我正在測試沒有任何主機應用程序的庫,因此沒有UIApplication對象。因此,不會調度.valueChanged事件,並且不會調用observe方法。

0

您正在測試方法內聲明觀察者對象。這意味着只要方法完成,它將從內存中釋放,因此不會被調用。創建一個對Tests類中的課堂級觀察員的引用,如下所示,它將起作用。

class Tests: XCTestCase { 

    var observer: ControlEventObserver! 
    func test() { 
     let myExpectation = expectation(description: "event fired") 
     self.observer = ControlEventObserver(expectation: myExpectation) 
     let control = MyControl() 
     control.addTarget(observer, action:#selector(ControlEventObserver.observe), for: .valueChanged) 
     control.fire() 
     waitForExpectations(timeout: 1) { error in 
      XCTAssertNil(error) 
     } 
    } 
} 

您還需要myExpectation & control以同樣的方式其他事物也不會被所謂的聲明。

+0

感謝您的回答。我認爲這些對象沒有被釋放,因爲我沒有創建任何自動釋放池。另外,我正在測試一個庫,以便測試目標沒有任何主機應用程序。我已經修改了我的問題以反映這一點。 –

相關問題