iosunit-testingmockingxctestswift3.2

Unit test cases - Swift 3.2


I have to write unit test case to check whether a particular method gets called or not from within the method which is being called from unit test case.

class A{
    func fetchPersonsData() {
       let b = B()
       b.sendDataToserver([])
     }
}

class B {
  func sendEventToServer(_:[]) {
  }
}

In my unit test case I will call fetchPersonsData() method and want to check whether it calls sentEventToServer(_:) or not and what are the params.

How to write test case for this in Swift 3.2?

Should I mock by creating subclass of class B and override required method and pass my test if required method gets called?


Solution

  • First add a protocol:

    protocol ServerSender {
        func sendEventToServer(_:[String])
    }
    

    Make B conform to that protocol:

    class B: ServerSender {
        func sendEventToServer(_:[String]) {
        }
    }
    

    In your test target add a mock:

    class BMock: ServerSender {
        var sendDataToServerCalled = false
        func sendEventToServer() {
            sendDataToServerCalled = true
        }
    }
    

    Change A to allow dependency injection:

    class A {
        lazy var b: ServerSender = B()
        func fetchPersonsData() {
            b.sendDataToServer([])
        }
     }
    

    In your test, inject the mock:

    func test_fetchPersonsData_sendsDataToServer() {
        let sut = A()
        let mock = BMock()
        sut.b = mock
    
        a.fetchPersonsData()
    
        XCTAssertTrue(mock.sendDataToServerCalled)
    }