samedi 29 août 2015

Unit Testing an Object and a Variable that conforms to a protocol in Swift

I have a VIPER architecture setup and am trying to unit test the instantiation of the wireframe.

For anyone who doesn't know what VIPER is, the key parts to understand are that there is are 4 classes that that have key responsibilities. The wireframe creates the other 3 (the view, presenter, and interactor). The wireframe then connects them appropriately like below:

                              Wireframe
                                  ^
                                  |
                                  v
                     View <-> Presenter <-> Interactor

So I am creating the unit tests in Swift, and am having difficulty making sure these connections are setup. Note, the code itself works, the asserts in the unit tests are the problem.

    func testInitWithNothingShouldInstantiateVIPERStackAndConnectLayers() {
            wireframe = LoginWireframe()       

            XCTAssertEqual(wireframe.modulePresenter, wireframe.moduleInteractor.presenter, "Interactor's presenter must be the module's presenter")

            XCTAssert(wireframe.modulePresenter === wireframe.moduleInteractor.presenter, "Interactor's presenter must be the module's presenter")
    }

Neither of these two asserts compiles correctly.

For the XCTAssertEqual this error occurs

Cannot find an overload for 'XCTAssertEqual' that accepts an argument list of type '(LoginPresenter, LoginInteractorOutput, String)'

For the XCTAssert (or XCTAssertTrue), this error occurs

Cannot invoke 'XCTAssert' with an argument list of type '(Bool, String)'

For completeness and because someone may find the code useful:

//LoginWireframe.swift
class LoginWireframe: NSObject, LoginWireframeInterface {
    lazy var moduleInteractor = LoginInteractor()
    lazy var modulePresenter = LoginPresenter()
    lazy var moduleView = LoginView()
    lazy var presenter : LoginRouting = self.modulePresenter

    override init() {
            super.init()

            let i = moduleInteractor
            let p = modulePresenter
            let v = moduleView

            i.presenter = p

            p.interactor = i
            p.view = v
            p.wireframe = self

            v.presenter = p

            presenter = p
}

//LoginInteractor.swift
class LoginInteractor: NSObject, LoginInteractorInput {
    lazy var presenter : LoginInteractorOutput = LoginPresenter()
}

//LoginPresenter.swift
class LoginPresenter : NSObject, LoginInteractorOutput, LoginPresenterInterface, LoginRouting {
    lazy var interactor : LoginInteractorInput = LoginInteractor()
    lazy var view : LoginViewInterface = LoginView()
    lazy var wireframe : LoginWireframeInterface = LoginWireframe()
}

//LoginView.swift
class LoginView : UIViewController, LoginViewInterface {
    lazy var presenter : LoginPresenterInterface = LoginPresenter()
 }

Aucun commentaire:

Enregistrer un commentaire