Nested function selector in swift for testing

2019-08-31 06:45发布

问题:

Here is my situation and perhaps there is an easier way to do this:

I'm testing some stuff that uses notifications and I didn't want to have to define my expectations as class level optional variables so I was wondering if I can make them local variables to a function in such a way that my notification handler can access them.

My attempt was to make notification handler functions as nested functions inside my top level test function - but i've run into selector naming issues as I'm not sure what I need to tell the notification handler to call

class FilePlayerTests: XCTestCase {

func testFilePlayback() {


    let f1URL : NSURL = NSBundle(forClass: FilePlayerTests.self).URLForResource("test1", withExtension: "csv")!
    let f2URL : NSURL = NSBundle(forClass: FilePlayerTests.self).URLForResource("test2", withExtension: "csv")!
    let f3URL : NSURL = NSBundle(forClass: FilePlayerTests.self).URLForResource("test3", withExtension: "csv")!

    let f1 = dm.createFilePlayerFromURL(f1URL)
    let f2 = dm.createFilePlayerFromURL(f2URL)
    let f3 = dm.createFilePlayerFromURL(f3URL)


    let e1 = expectationWithDescription("xplane1")
    let e2 = expectationWithDescription("xplane2")
    let e3 = expectationWithDescription("xplane3")



    f1?.startPlayback()


    //Define LocationMessage Observer
    nc.addObserver(self, selector: "newHandler:",
        name: dmNotification.LocationData.rawValue,
        object: nil)


    ///Prints out a new Location Message
    func newHandler(notif: NSNotification) {
        let msg = notif.asLocationMessage!
        println(msg)

        e1.fulfill()
    }

}
}

So my code is crashing because it can't find the selector.

1) Is this valid?

2) How would i name the selector correctly so it could be found?

回答1:

The problem is that you are saying this:

nc.addObserver(self, selector: "newHandler:" ...

But self, the FilePlayerTests class, has no selector called newHandler: - because you have defined that function only as a local function inside the testFilePlayback function. It exists only locally - only in the eyes of code that runs after it inside the testFilePlayback function - and only very temporarily, i.e. while testFilePlayback is running.

You must define newHandler: at the top level of the FilePlayerTests class so that it is a method that the notification center can actually call.

That may (i.e. will) mean that you will have to promote some other stuff in your method to top level as well, of course.