Logo

dev-resources.site

for different kinds of informations.

Tests Everywhere - Swift

Published at
12/18/2023
Categories
test
swift
xctest
cuckoo
Author
Roger Viñas Alcon
Categories
4 categories in total
test
open
swift
open
xctest
open
cuckoo
open
Tests Everywhere - Swift

GitHub logo rogervinas / tests-everywhere

🤠 Tests, Tests Everywhere!

Swift testing this simple Hello World with XCTest and Cuckoo

Show me the code

Implementation

Sorry but reading that constant and variable names can contain almost any character, including Unicode characters I could not resist 😅 ...

1) Create HelloMessage class in HelloMessage.swift:

class HelloMessage {
  var 👋: String {
    get {
      return "Hello World!"
    }
  }
}

2) Same way create HelloConsole class in HelloConsole.swift:

class HelloConsole {
  func print(👋: String) {
    Swift.print(👋)
  }
}

3) Create HelloApp class in HelloApp.swift:

class HelloApp {

  let message: HelloMessage
  let console: HelloConsole

  init(message: HelloMessage, console: HelloConsole) {
    self.message = message
    self.console = console
  }

  func printHello() {
    console.print(👋: message.👋)
  }
}

4) Create main class in Main.swift that wraps it all together:

@main
public struct Main {
  public static func main() {
    let message = HelloMessage()
    let console = HelloConsole()
    let app = HelloApp(message: message, console: console)
    app.printHello()
  }
}

Test

Following XCTest and Cuckoo guides ...

1) Mock generation

Mocks have to be generated statically, you can follow these instructions or alternatively:

git clone [email protected]:Brightify/Cuckoo.git /tmp/Cuckoo
/tmp/Cuckoo/build_generator
  • Generate mocks (as many times as needed):
/tmp/Cuckoo/Generator/bin/cuckoo_generator generate \
  --testable Hello \
  --output Tests/Mocks.swift \
  Sources/HelloMessage.swift \
  Sources/HelloConsole.swift

You can also integrate mocks generation in the build, before compile phase.

2) Test HelloMessage in HelloMessageTest.swift:

final class HelloMessageTest: XCTestCase {
  func testHelloMessageShouldReturnHelloWorld() throws {
    let message = HelloMessage()
    XCTAssertEqual(message.👋, "Hello World!")
  }
}

3) Test HelloApp in HelloAppTest.swift:

final class HelloAppTest: XCTestCase {
  func testHelloAppShouldDisplayHelloMessage() throws {
    let messageText = "Hello Test!"
    // 2.1 Create a mock of HelloMessage
    let message = MockHelloMessage()
    // 2.2 Return "Hello Test!" whenever 👋 getter is called
    stub(message) { stub in
      when(stub.👋.get).thenReturn(messageText)
    }

    // 2.2 Create a mock of HelloConsole
    let console = MockHelloConsole()
    // 2.3 Do nothing whenever print is called
    stub(console) { stub in
      when(stub.print(👋: anyString())).thenDoNothing()
    }

    // 2.4 Create a HelloApp, the one we want to test, passing the mocks
    let app = HelloApp(message: message, console: console)
    // 2.5 Execute the method we want to test
    app.printHello()

    // 2.6 Verify HelloConsole mock print() method
    // has been called once with "Hello Test!"
    verify(console).print(👋: messageText)
  }
}

4) Test output should look like:

Test Suite 'All tests' started at 2023-12-12 16:48:21.225
Test Suite 'debug.xctest' started at 2023-12-12 16:48:21.227
Test Suite 'HelloAppTest' started at 2023-12-12 16:48:21.227
Test Case 'HelloAppTest.testHelloAppShouldDisplayHelloMessage' started at 2023-12-12 16:48:21.227
Test Case 'HelloAppTest.testHelloAppShouldDisplayHelloMessage' passed (0.003 seconds)
Test Suite 'HelloAppTest' passed at 2023-12-12 16:48:21.230
    Executed 1 test, with 0 failures (0 unexpected) in 0.003 (0.003) seconds
Test Suite 'HelloMessageTest' started at 2023-12-12 16:48:21.230
Test Case 'HelloMessageTest.testHelloMessageShouldReturnHelloWorld' started at 2023-12-12 16:48:21.231
Test Case 'HelloMessageTest.testHelloMessageShouldReturnHelloWorld' passed (0.001 seconds)
Test Suite 'HelloMessageTest' passed at 2023-12-12 16:48:21.232
    Executed 1 test, with 0 failures (0 unexpected) in 0.001 (0.001) seconds
Test Suite 'debug.xctest' passed at 2023-12-12 16:48:21.232
    Executed 2 tests, with 0 failures (0 unexpected) in 0.004 (0.004) seconds
Test Suite 'All tests' passed at 2023-12-12 16:48:21.232
    Executed 2 tests, with 0 failures (0 unexpected) in 0.004 (0.004) seconds

Happy Testing! 💙

Featured ones: