sabirvirtuoso/Mockit

View on GitHub
Example/Tests/CallHandlerTests.swift

Summary

Maintainability
F
5 days
Test Coverage
//
//  Mockit
//
//  Copyright (c) 2016 Syed Sabir Salman-Al-Musawi <sabirvirtuoso@gmail.com>
//
//  Permission is hereby granted, free of charge, to any person obtaining a copy
//  of this software and associated documentation files (the "Software"), to deal
//  in the Software without restriction, including without limitation the rights
//  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//  copies of the Software, and to permit persons to whom the Software is
//  furnished to do so, subject to the following conditions:
//
//  The above copyright notice and this permission notice shall be included in
//  all copies or substantial portions of the Software.
//
//  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//  THE SOFTWARE.
//

import XCTest
import Mockit


// MARK:- An implementation of `Mock` protocol


class MockImplementation: Mock {

  var callHandler: CallHandler

  init(withCallHandler callHandler: CallHandler) {
    self.callHandler = callHandler
  }

  func instanceType() -> MockImplementation {
    return self
  }

  func doSomethingWithNonOptionalArguments(_ arg1: String, arg2: Int) -> Int {
    return callHandler.accept(0, ofFunction: #function, atFile: #file, inLine: #line, withArgs: arg1, arg2) as! Int
  }

  func doSomethingWithNoArguments() {
    let _ = callHandler.accept(nil, ofFunction: #function, atFile: #file, inLine: #line, withArgs: nil)
  }

  func doSomethingWithSomeOptionalArguments(_ arg1: String?, arg2: Int) {
    let _ = callHandler.accept(nil, ofFunction: #function, atFile: #file, inLine: #line, withArgs: arg1, arg2)
  }

}


// MARK:- A test implementation of `MockFailer` protocol


class Failer: MockFailer {

  var message: String?
  var file: String?
  var line: Int?

  func doFail(_ message: String, file: String, line: Int) {
    self.message = message
    self.file = file
    self.line = line
  }

}


// MARK:- CallHandlerTests setup


class CallHandlerTests: XCTestCase {

  var mockImplementation: MockImplementation!
  let failer = Failer()
  var sut: CallHandlerImpl!

  override func setUp() {
    sut = CallHandlerImpl(withFailer: failer)
    mockImplementation = MockImplementation(withCallHandler: sut)
  }

}


// MARK:- Test cases for CallHandler state `When`


extension CallHandlerTests {

  func testCallingStubOnceWithNonOptionalArgumentsReturnsValueByPerformingActionsOnSuccessfulStubMatching() {
    // Given
    let _ = mockImplementation.when().call(withReturnValue: mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)).thenReturn(42)

    // When
    let returnValue = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)

    // Then
    XCTAssertEqual(returnValue, 42)
  }

  func testCallingStubMultipleTimesWithNonOptionalArgumentsReturnsValueByPerformingActionsOnSuccessfulStubMatching() {
    // Given
    let _ = mockImplementation.when().call(withReturnValue: mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)).thenReturn(42, 18)

    // When
    let returnValueOfFirstCall = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)
    let returnValueOfSecondCall = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)

    // Then
    XCTAssertEqual(returnValueOfFirstCall, 42)
    XCTAssertEqual(returnValueOfSecondCall, 18)
  }

  func testCallingStubOnceWithOptionalArgumentsReturnsValueByPerformingActionsOnSuccessfulStubMatching() {
    // Given
    var flag = false

    let _ = mockImplementation.when().call(withReturnValue: mockImplementation.doSomethingWithSomeOptionalArguments(nil, arg2: 1)).thenDo {
      (args: [Any?]) -> Void in

      flag = true
    }

    // When
    mockImplementation.doSomethingWithSomeOptionalArguments(nil, arg2: 1)

    // Then
    XCTAssertTrue(flag)
  }

  func testCallingStubMultipleTimesWithOptionalArgumentsReturnsValueByPerformingActionsOnSuccessfulStubMatching() {
    // Given
    var array = [0, 0]

    let _ = mockImplementation.when().call(withReturnValue: mockImplementation.doSomethingWithSomeOptionalArguments(nil, arg2: 1)).thenDo {
      (args: [Any?]) -> Void in

      array[0] = 1
    }.thenDo {
      (args: [Any?]) -> Void in

      array[1] = 2
    }

    // When
    mockImplementation.doSomethingWithSomeOptionalArguments(nil, arg2: 1)
    mockImplementation.doSomethingWithSomeOptionalArguments(nil, arg2: 1)

    // Then
    XCTAssertEqual(array[0], 1)
    XCTAssertEqual(array[1], 2)
  }

  func testCallingStubReturnsDefaultValueOnUnsuccessfulStubMatching() {
    // Given
    let _ = mockImplementation.when().call(withReturnValue: mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)).thenReturn(42)

    // When
    let returnValue = mockImplementation.doSomethingWithNonOptionalArguments("two", arg2: 1)

    // Then
    XCTAssertEqual(returnValue, 0)
  }

  func testCallingMethodForWhichNoStubIsRegisteredReturnsDefaultValue() {
    // Given

    // When
    let returnValue = mockImplementation.doSomethingWithNonOptionalArguments("two", arg2: 1)

    // Then
    XCTAssertEqual(returnValue, 0)
  }

}


// MARK:- Test cases for CallHandler state `Verify`


extension CallHandlerTests {

  func testVerificationModeOnceSucceedsWhenMethodIsCalledOnce() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)

    // When
    let _ = mockImplementation.verify(verificationMode: Once()).doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int)

    // Then
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)
  }

  func testVerificationModeOnceFailsWhenMethodIsCalledMoreThanOnce() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)
    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)

    // When
    let _ = (mockImplementation.verify(verificationMode: Once())).doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int)

    // Then
    XCTAssertNotNil(failer.message)
    XCTAssertNotNil(failer.file)
    XCTAssertNotNil(failer.line)
  }

  func testVerificationModeAtLeastOnceSucceedsWhenMethodIsCalledOnce() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)

    // When
    let _ = mockImplementation.verify(verificationMode: AtLeastOnce()).doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int)

    // Then
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)
  }

  func testVerificationModeAtLeastOnceSucceedsWhenMethodIsCalledMoreThanOnce() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    let _ = mockImplementation.doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int)
    let _ = mockImplementation.doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int)

    // When
    let _ = mockImplementation.verify(verificationMode: AtLeastOnce()).doSomethingWithNonOptionalArguments("one", arg2: 1)

    // Then
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)
  }

  func testVerificationModeAtLeastOnceFailsWhenMethodIsCalledLessThanOnce() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    // When
    let _ = mockImplementation.verify(verificationMode: AtLeastOnce()).doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int)

    // Then
    XCTAssertNotNil(failer.message)
    XCTAssertNotNil(failer.file)
    XCTAssertNotNil(failer.line)
  }

  func testVerificationModeAtMostOnceSucceedsWhenMethodIsCalledOnce() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)

    // When
    let _ = mockImplementation.verify(verificationMode: AtMostOnce()).doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int)

    // Then
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)
  }

  func testVerificationModeAtMostOnceSucceedsWhenMethodIsCalledLessThanOnce() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    // When
    let _ = mockImplementation.verify(verificationMode: AtMostOnce()).doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int)

    // Then
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)
  }

  func testVerificationModeAtMostOnceFailsWhenMethodIsCalledMoreThanOnce() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)
    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)

    // When
    let _ = mockImplementation.verify(verificationMode: AtMostOnce()).doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int)

    // Then
    XCTAssertNotNil(failer.message)
    XCTAssertNotNil(failer.file)
    XCTAssertNotNil(failer.line)
  }

  func testVerificationModeTimesSucceedsWhenMethodIsCalledGivenTimes() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)
    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)

    // When
    let _ = mockImplementation.verify(verificationMode: Times(times: 2)).doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int)

    // Then
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)
  }

  func testVerificationModeTimesFailsWhenMethodIsCalledLessThanGivenTimes() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)

    // When
    let _ = mockImplementation.verify(verificationMode: Times(times: 2)).doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int)

    // Then
    XCTAssertNotNil(failer.message)
    XCTAssertNotNil(failer.file)
    XCTAssertNotNil(failer.line)
  }

  func testVerificationModeTimesFailsWhenMethodIsCalledMoreThanGivenTimes() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)
    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)
    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)

    // When
    let _ = mockImplementation.verify(verificationMode: Times(times: 2)).doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int)

    // Then
    XCTAssertNotNil(failer.message)
    XCTAssertNotNil(failer.file)
    XCTAssertNotNil(failer.line)
  }

  func testVerificationModeAtLeastTimesSucceedsWhenMethodIsCalledGivenTimes() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)
    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)

    // When
    let _ = mockImplementation.verify(verificationMode: AtLeastTimes(times: Times(times: 2))).doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int)

    // Then
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)
  }

  func testVerificationModeAtLeastTimesSucceedsWhenMethodIsCalledMoreThanGivenTimes() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)
    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)
    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)

    // When
    let _ = mockImplementation.verify(verificationMode: AtLeastTimes(times: Times(times: 2))).doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int)

    // Then
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)
  }

  func testVerificationModeAtLeastTimesFailsWhenMethodIsCalledLessThanGivenTimes() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)

    // When
    let _ = mockImplementation.verify(verificationMode: AtLeastTimes(times: Times(times: 2))).doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int)

    // Then
    XCTAssertNotNil(failer.message)
    XCTAssertNotNil(failer.file)
    XCTAssertNotNil(failer.line)
  }

  func testVerificationModeAtMostTimesSucceedsWhenMethodIsCalledGivenTimes() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)
    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)

    // When
    let _ = mockImplementation.verify(verificationMode: AtMostTimes(times: Times(times: 2))).doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int)

    // Then
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)
  }

  func testVerificationModeAtMostTimesFailsWhenMethodIsCalledMoreThanGivenTimes() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)
    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)
    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)

    // When
    let _ = mockImplementation.verify(verificationMode: AtMostTimes(times: Times(times: 2))).doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int)

    // Then
    XCTAssertNotNil(failer.message)
    XCTAssertNotNil(failer.file)
    XCTAssertNotNil(failer.line)
  }

  func testVerificationModeAtMostTimesSucceedsWhenMethodIsCalledLessThanGivenTimes() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)

    // When
    let _ = mockImplementation.verify(verificationMode: AtMostTimes(times: Times(times: 2))).doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int)

    // Then
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)
  }

  func testVerificationModeNeverSucceedsWhenMethodIsNeverCalled() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    // When
    let _ = mockImplementation.verify(verificationMode: Never()).doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int)

    // Then
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)
  }

  func testVerificationModeNeverFailWhenMethodIsCalled() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)

    // When
    let _ = mockImplementation.verify(verificationMode: Never()).doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int)

    // Then
    XCTAssertNotNil(failer.message)
    XCTAssertNotNil(failer.file)
    XCTAssertNotNil(failer.line)
  }

  func testVerificationModeOnlySucceedsWhenMethodIsOnlyCalled() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)

    // When
    let _ = mockImplementation.verify(verificationMode: Only()).doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int)

    // Then
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)
  }

  func testVerificationModeOnlyFailsWhenMethodIsNotOnlyCalled() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    mockImplementation.doSomethingWithNoArguments()
    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)

    // When
    let _ = mockImplementation.verify(verificationMode: Only()).doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int)

    // Then
    XCTAssertNotNil(failer.message)
    XCTAssertNotNil(failer.file)
    XCTAssertNotNil(failer.line)
  }

}


// MARK:- Test cases for CallHandler state `GetArgs`


extension CallHandlerTests {

  func testGetArgsFailsWhenCallOrderIsZero() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)

    // When
    let _ = mockImplementation.getArgs(callOrder: 0).of(mockImplementation.doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int))

    // Then
    XCTAssertEqual(failer.message, "Call Order of a method must be greater than 0")
    XCTAssertNotNil(failer.file)
    XCTAssertNotNil(failer.line)
  }

  func testGetArgsFailsWhenCallOrderIsNonZeroButMethodIsNeverCalled() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    // When
    let _ = mockImplementation.getArgs(callOrder: 2).of(mockImplementation.doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int))

    // Then
    XCTAssertNotNil(failer.message)
    XCTAssertNotNil(failer.file)
    XCTAssertNotNil(failer.line)
  }

  func testGetArgsFailsWhenCallOrderIsGreaterThanNumberOfTimesMethodIsCalled() {
    // Given
    XCTAssertNil(failer.message)
    XCTAssertNil(failer.file)
    XCTAssertNil(failer.line)

    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 1)

    // When
    let _ = mockImplementation.getArgs(callOrder: 2).of(mockImplementation.doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int))

    // Then
    XCTAssertNotNil(failer.message)
    XCTAssertNotNil(failer.file)
    XCTAssertNotNil(failer.line)
  }

  func testGetArgsReturnsCorrectNonNilArgumentsWhenMethodIsCalledOnce() {
    // Given
    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 2)

    // When
    let arguments = mockImplementation.getArgs(callOrder: 1).of(mockImplementation.doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int))

    // Then
    XCTAssertEqual(arguments![0] as? String, "one")
    XCTAssertEqual(arguments![1] as? Int, 2)
  }

  func testGetArgsReturnsCorrectNilArgumentsWhenMethodIsCalledOnce() {
    // Given
    mockImplementation.doSomethingWithSomeOptionalArguments(nil, arg2: 2)

    // When
    let arguments = mockImplementation.getArgs(callOrder: 1).of(mockImplementation.doSomethingWithSomeOptionalArguments(AnyValue.string, arg2: AnyValue.int))

    // Then
    XCTAssertNil(arguments![0])
    XCTAssertEqual(arguments![1] as? Int, 2)
  }

  func testGetArgsReturnsCorrectNonNilArgumentsWhenMethodIsCalledMultipleTimes() {
    // Given
    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 2)
    let _ = mockImplementation.doSomethingWithNonOptionalArguments("two", arg2: 3)

    // When
    let argumentsOfFirstCall = mockImplementation.getArgs(callOrder: 1).of(mockImplementation.doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int))
    let argumentsOfSecondCall = mockImplementation.getArgs(callOrder: 2).of(mockImplementation.doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int))

    // Then
    XCTAssertEqual(argumentsOfFirstCall![0] as? String, "one")
    XCTAssertEqual(argumentsOfFirstCall![1] as? Int, 2)

    XCTAssertEqual(argumentsOfSecondCall![0] as? String, "two")
    XCTAssertEqual(argumentsOfSecondCall![1] as? Int, 3)
  }

  func testGetArgsReturnsCorrectNonNilArgumentsWhenMultipleMethodsAreCalled() {
    // Given
    let _ = mockImplementation.doSomethingWithNonOptionalArguments("one", arg2: 2)
    let _ = mockImplementation.doSomethingWithSomeOptionalArguments("two", arg2: 4)

    // When
    let argumentsOfFirstMethod = mockImplementation.getArgs(callOrder: 1).of(mockImplementation.doSomethingWithNonOptionalArguments(AnyValue.string, arg2: AnyValue.int))
    let argumentsOfSecondMethod = mockImplementation.getArgs(callOrder: 1).of(mockImplementation.doSomethingWithSomeOptionalArguments(AnyValue.string, arg2: AnyValue.int))

    // Then
    XCTAssertEqual(argumentsOfFirstMethod![0] as? String, "one")
    XCTAssertEqual(argumentsOfFirstMethod![1] as? Int, 2)

    XCTAssertEqual(argumentsOfSecondMethod![0] as? String, "two")
    XCTAssertEqual(argumentsOfSecondMethod![1] as? Int, 4)
  }

}