Swinject & XCode UI Tests

Created on 28 Oct 2016  路  5Comments  路  Source: Swinject/Swinject

Is there a best practice to change the Container configuration in a XCode UI Test, to mock for example a RestClient-Class that implements a Protocol that I could mock?

question

Most helpful comment

Sure thing. I've got a MainAssembler class where I apply all my Assemblies in the constructor. The MainAssembler class is instantiated by my AppDelegate.

class MainAssembler {
    let assembler: Assembler

    init() {
        assembler = Assembler(container: SwinjectStoryboard.defaultContainer)
        assembler.apply(assemblies: MyAssemblies.assemblies)

        // Apply UITest Assemblies after applying regular assemblies to achieve overwriting of 
        // registrations.
        let processInfo = ProcessInfo.processInfo
        if processInfo.arguments.contains("UITests") {
            assembler.apply(assemblies: UITestAssemblies.assemblies)
        }
    }
}

// I use non-instantiatable structs to achieve namespacing.
struct UITestAssemblies {
    // Static property to hold all my assemblies for organizational purposes.
    static let assemblies: [AssemblyType] = [...]

    private init() { }
}

@UIApplicationMain
class AppDelegate: UIResponder {
    let mainAssembler = MainAssembler()
}

Then, in my UI Tests, I set the launch argument:

class MyUITest: XCTestCase {
    let app = XCUIApplication()

    override func setUp() {
        super.setUp()

        continueAfterFailure = false

        app.launchArguments.append("UITests")
        app.launch()
    }
}

You can organize your Assemblies however you want, but the main point is to use the launch argument to trigger your UITest assemblies to override certain registrations when performing UITests.

All 5 comments

What I do is I pass a launch argument to the app in my UI test target. In my app's AppDelegate, I process this argument from ProcessInfo.processInfo.arguments.

If I find my UITest argument, I apply a special UI test assembly to my assembler which overrides all of the registries I'd like to mock out for UI tests. I also make sure to apply the test assembly after all my main assemblies are applied.

Thanks @thalmicMark for the nice practice. I've never tried Swinject with Xcode UI Test. @thalmicMark's practice is the best practice as far as I know. @sialcasa, did it fit in your case?

Please feel free to reopen this issue if the practice didn't fit in your case.

@thalmicMark can you provide an example of how this works for you? i'm embarking on a simliar ui test journey.

Sure thing. I've got a MainAssembler class where I apply all my Assemblies in the constructor. The MainAssembler class is instantiated by my AppDelegate.

class MainAssembler {
    let assembler: Assembler

    init() {
        assembler = Assembler(container: SwinjectStoryboard.defaultContainer)
        assembler.apply(assemblies: MyAssemblies.assemblies)

        // Apply UITest Assemblies after applying regular assemblies to achieve overwriting of 
        // registrations.
        let processInfo = ProcessInfo.processInfo
        if processInfo.arguments.contains("UITests") {
            assembler.apply(assemblies: UITestAssemblies.assemblies)
        }
    }
}

// I use non-instantiatable structs to achieve namespacing.
struct UITestAssemblies {
    // Static property to hold all my assemblies for organizational purposes.
    static let assemblies: [AssemblyType] = [...]

    private init() { }
}

@UIApplicationMain
class AppDelegate: UIResponder {
    let mainAssembler = MainAssembler()
}

Then, in my UI Tests, I set the launch argument:

class MyUITest: XCTestCase {
    let app = XCUIApplication()

    override func setUp() {
        super.setUp()

        continueAfterFailure = false

        app.launchArguments.append("UITests")
        app.launch()
    }
}

You can organize your Assemblies however you want, but the main point is to use the launch argument to trigger your UITest assemblies to override certain registrations when performing UITests.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

grzegorzkrukowski picture grzegorzkrukowski  路  7Comments

Mijail picture Mijail  路  6Comments

thalmicMark picture thalmicMark  路  6Comments

diwengrum picture diwengrum  路  5Comments

movses-margaryan picture movses-margaryan  路  5Comments