prolificinteractive/Yoshi

How to unit test a Yoshi integration with asyncAfterDismissing

ThibaultKlein opened this issue · 2 comments

Hi,

I'm trying to find a way to unit test my Yoshi integration using mock objects. Let me show you the use case I have right now.

I have a bug reporter tool that gets invoked when I tap on the Yoshi menu item. Here is the code I have for the implementation of it:

internal struct DebugMenuItem: YoshiMenu {

    let title: String
    let subtitle: String?
    let executeAction: () -> YoshiActionResult

    init(title: String, subtitle: String?, executeAction: @escaping () -> YoshiActionResult) {
        self.title = title
        self.subtitle = subtitle
        self.executeAction = executeAction
    }

    func execute() -> YoshiActionResult {
        return executeAction()
    }

}
let bugReportMenuItem = DebugMenuItem(title: title, subtitle: nil) { () -> YoshiActionResult in
        return YoshiActionResult.asyncAfterDismissing({ 
            self.bugReporter.invoke()
    })
}

And here is my mock object:

internal final class FakeBugReporter: BugReporter {

    var didSetup = false
    var didInvoke = false

    func setup() {
        didSetup = true
    }

    func invoke() {
        didInvoke = true
    }

}

Finally, here is my test:

class BugReporterDebugBuilderTests: XCTestCase {
    
    func testBugReporterMenuItemInvokeActionTapped() {
        // Given
        let bugReporter = FakeBugReporter()
        let bugReporterBuilder = BugReporterDebugBuilder(bugReporter: bugReporter)
        let item = bugReporterBuilder.buildBugReporterMenuItem()
        // When
        let _ = item.execute()
        // Then
        XCTAssertTrue(bugReporter.didInvoke) // Fails here, due to async after dismissing behavior
    }
    
}

What's your recommendation to make sure that my invoke() function is called inside asyncAfterDismissing? Is there a way to unit test that?

Thanks!

@ThibaultKlein Sorry for the late reply. Since Yoshi's action is triggered by table view delegation, there's no direct way to test cell's action if the cell and Yoshi view itself are not displaying.

Since debugNavigationController is exposed in 2.2.0. One way to test it is to display Yoshi by calling Yoshi.show, and iterate its debugNavigationController to find the tableview and the cell to be tested, trigger the selection event manually and test the result.

After that, you can use XCTest's expectation to check the result asynchronously.

@ThibaultKlein Closing for now, let me know if you have any more questions