Skip to content

Establish a unique pattern for testing UIViewController presentation #19373

@mokagio

Description

@mokagio

See discussion here.

One options suggested is to use a mock:

let presenterMock = PresenterMockViewController()
...
presenter.presentReblog(blogService: blogService!, readerPost: readerPost!, origin: presenterMock)
...
presenterMock.expectPresentationToOccurr()

// In PresenterMockViewController
func expectPresentationToOccurr(file: ... = #file, line: ... = #line) {
  guard let presentExpectation = self.presentExpectation else { /* fail */ }

  waitForExpectations([presentExpectation], timeout: ...) { error in
    guard let error = error else { return }
    XCTFail("present was not called", file: file, line: line)
  }
}

Another option I used with good results in the past is the classic protocol-based test double. Something like:

protocol ViewControllerPresenting {

  // 1-1 copy of the UIViewController signature
  func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)? = nil)
}

extension UIViewController: ViewControllerPresenting {}

class ViewControllerPresentingSpy {

  private(set) var presentedViewController: UIViewController?

  func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)? = nil) {
    presentedViewController = viewControllerToPresent
    // doesn't actually present so we don't waste time nor need to worry about async
  }
}

// In tests
expect(presenterSpy.presentedViewController).toNot(beNil())

☝️ All those are just ideas to throw in the mix. We ought to have a look at what the existing tests do and what production code needs, and then choose an option that works best.


Tests to update

Anyone with contributor access can update this list by updating the PR description. Seems easier than adding comments to scroll through.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions