315 lines
12 KiB
Swift
315 lines
12 KiB
Swift
//
|
|
// StubbingTest.swift
|
|
// Cuckoo
|
|
//
|
|
// Created by Filip Dolnik on 04.07.16.
|
|
// Copyright © 2016 Brightify. All rights reserved.
|
|
//
|
|
|
|
import XCTest
|
|
@testable import Cuckoo
|
|
|
|
class StubbingTest: XCTestCase {
|
|
|
|
func testMultipleReturns() {
|
|
let mock = MockTestedClass()
|
|
stub(mock) { mock in
|
|
when(mock.readOnlyProperty.get).thenReturn("a").thenReturn("b", "c")
|
|
}
|
|
|
|
XCTAssertEqual(mock.readOnlyProperty, "a")
|
|
XCTAssertEqual(mock.readOnlyProperty, "b")
|
|
XCTAssertEqual(mock.readOnlyProperty, "c")
|
|
XCTAssertEqual(mock.readOnlyProperty, "c")
|
|
}
|
|
|
|
func testOverrideStubWithMoreGeneralParameterMatcher() {
|
|
let mock = MockTestedClass()
|
|
stub(mock) { mock in
|
|
when(mock.count(characters: "a")).thenReturn(2)
|
|
when(mock.count(characters: anyString())).thenReturn(1)
|
|
}
|
|
|
|
XCTAssertEqual(mock.count(characters: "a"), 1)
|
|
}
|
|
|
|
func testOverrideStubWithMoreSpecificParameterMatcher() {
|
|
let mock = MockTestedClass()
|
|
stub(mock) { mock in
|
|
when(mock.count(characters: anyString())).thenReturn(1)
|
|
when(mock.count(characters: "a")).thenReturn(2)
|
|
}
|
|
|
|
XCTAssertEqual(mock.count(characters: "a"), 2)
|
|
}
|
|
|
|
func testUnstubbedSpy() {
|
|
let mock = MockTestedClass().withEnabledSuperclassSpy()
|
|
|
|
XCTAssertEqual(mock.count(characters: "a"), 1)
|
|
}
|
|
|
|
func testStubOfMultipleDifferentCalls() {
|
|
let mock = MockTestedClass()
|
|
stub(mock) { mock in
|
|
when(mock.readOnlyProperty.get).thenReturn("a")
|
|
when(mock.count(characters: "a")).thenReturn(1)
|
|
}
|
|
|
|
XCTAssertEqual(mock.readOnlyProperty, "a")
|
|
XCTAssertEqual(mock.count(characters: "a"), 1)
|
|
}
|
|
|
|
func testSubClass() {
|
|
let mock = MockTestedSubclass()
|
|
|
|
XCTAssertNotNil(mock)
|
|
|
|
stub(mock) { mock in
|
|
when(mock.readOnlyProperty.get).thenReturn("a").thenReturn("b", "c")
|
|
}
|
|
|
|
XCTAssertEqual(mock.readOnlyProperty, "a")
|
|
XCTAssertEqual(mock.readOnlyProperty, "b")
|
|
XCTAssertEqual(mock.readOnlyProperty, "c")
|
|
XCTAssertEqual(mock.readOnlyProperty, "c")
|
|
}
|
|
|
|
func testSubClassMethod() {
|
|
let mock = MockTestedSubclass()
|
|
|
|
XCTAssertNotNil(mock)
|
|
|
|
stub(mock) { mock in
|
|
when(mock.subclassMethod()).thenReturn(1)
|
|
}
|
|
|
|
XCTAssertEqual(mock.subclassMethod(), 1)
|
|
}
|
|
|
|
func testSubclassMethodWithStringParameter() {
|
|
let mock = MockTestedSubclass()
|
|
|
|
XCTAssertNotNil(mock)
|
|
|
|
stub(mock) { mock in
|
|
when(mock.methodWithParameter(anyInt())).thenReturn("t1")
|
|
when(mock.methodWithParameter(anyString())).thenReturn("t")
|
|
}
|
|
|
|
XCTAssertEqual(mock.methodWithParameter("a"), "t")
|
|
}
|
|
|
|
func testSubclassMethodWithIntParameter() {
|
|
let mock = MockTestedSubclass()
|
|
|
|
XCTAssertNotNil(mock)
|
|
|
|
stub(mock) { mock in
|
|
when(mock.methodWithParameter(anyInt())).thenReturn("t1")
|
|
when(mock.methodWithParameter(anyString())).thenReturn("s1")
|
|
}
|
|
|
|
XCTAssertEqual(mock.methodWithParameter(1), "t1")
|
|
}
|
|
|
|
func testSubclassProtocolExtensionMethod() {
|
|
/// Test dynamic dispatching
|
|
let mock = MockTestedSubclass()
|
|
|
|
XCTAssertNotNil(mock)
|
|
|
|
stub(mock) { mock in
|
|
when(mock.protocolMethod()).thenReturn("a1")
|
|
}
|
|
|
|
XCTAssertEqual(mock.protocolMethod(), "a1")
|
|
}
|
|
|
|
func testSubclassWithGrandparentsInheritanceAcceptanceTest() {
|
|
let mock = MockTestedSubSubClass()
|
|
|
|
XCTAssertNotNil(mock)
|
|
|
|
var setReadWriteProperty: Int = -1
|
|
var setOptionalProperty = -1
|
|
var callNoReturn = false
|
|
var callNoReturnThrows = false
|
|
var callWithEscape = false
|
|
var callWithOptionalClosure = false
|
|
var callWithLabelAndUnderscore = false
|
|
|
|
// Mock all available functions
|
|
stub(mock) { stub in
|
|
// sub-sub class
|
|
when(stub.subSubMethod()).thenReturn("not nil")
|
|
|
|
// sub-class
|
|
when(stub.withImplicitlyUnwrappedOptional(i: anyInt())).thenReturn("implicit unwrapped return")
|
|
when(stub.withThrows()).thenReturn(10)
|
|
when(stub.withNamedTuple(tuple: any())).thenReturn(11)
|
|
when(stub.subclassMethod()).thenReturn(12)
|
|
// when(stub.withOptionalClosureAndReturn(anyString(), closure: isNil())).thenReturn(2)
|
|
when(stub.withClosureAndParam(anyString(), closure: anyClosure())).thenReturn(3)
|
|
when(stub.withMultClosures(closure: anyClosure(), closureB: anyClosure(), closureC: anyClosure())).thenReturn(4)
|
|
when(stub.withThrowingClosure(closure: anyThrowingClosure())).thenReturn("throwing closure")
|
|
when(stub.withThrowingClosureThrows(closure: anyThrowingClosure())).thenReturn("closure throwing")
|
|
when(stub.withThrowingEscapingClosure(closure: anyThrowingClosure())).thenReturn("escaping closure")
|
|
// when(stub.withThrowingOptionalClosureThrows(closure: anyOptionalThrowingClosure())).thenReturn("optional closure throwing")
|
|
when(stub.methodWithParameter(anyString())).thenReturn("parameter string")
|
|
when(stub.methodWithParameter(anyInt())).thenReturn("parameter int")
|
|
|
|
// class
|
|
when(stub.privateSetProperty.get).thenReturn(5)
|
|
when(stub.readOnlyProperty.get).thenReturn("b")
|
|
when(stub.readWriteProperty.set(anyInt())).then { i in
|
|
setReadWriteProperty = i
|
|
}
|
|
when(stub.readWriteProperty.get).thenReturn(7)
|
|
when(stub.optionalProperty.set(anyInt())).then { i in
|
|
setOptionalProperty = i!
|
|
}
|
|
when(stub.optionalProperty.get).thenReturn(8)
|
|
when(stub.noReturn()).then { _ in
|
|
callNoReturn = true
|
|
}
|
|
when(stub.count(characters: anyString())).thenReturn(9)
|
|
when(stub.withNoReturnThrows()).then { _ in
|
|
callNoReturnThrows = true
|
|
}
|
|
when(stub.withClosure(anyClosure())).thenReturn(14)
|
|
when(stub.withEscape(anyString(), action: anyClosure())).then { _ in
|
|
callWithEscape = true
|
|
}
|
|
when(stub.withOptionalClosure(anyString(), closure: anyClosure())).then { _ in
|
|
callWithOptionalClosure = true
|
|
}
|
|
when(stub.withLabelAndUnderscore(labelA: anyString(), anyString())).then { _ in
|
|
callWithLabelAndUnderscore = true
|
|
}
|
|
when(stub.callingCountCharactersMethodWithHello()).thenReturn(15)
|
|
|
|
// protocol
|
|
when(stub.protocolMethod()).thenReturn("protocol method")
|
|
}
|
|
|
|
//
|
|
// Test stubbing
|
|
XCTAssertEqual(mock.subSubMethod(), "not nil")
|
|
|
|
// sub-class
|
|
XCTAssertEqual(mock.withImplicitlyUnwrappedOptional(i: 0), "implicit unwrapped return")
|
|
XCTAssertEqual(try! mock.withThrows(), 10)
|
|
XCTAssertEqual(mock.withNamedTuple(tuple: (a: "A", b: "B")), 11)
|
|
XCTAssertEqual(mock.subclassMethod(), 12)
|
|
XCTAssertEqual(mock.withOptionalClosureAndReturn("a", closure: nil), 2)
|
|
XCTAssertEqual(mock.withClosureAndParam("a", closure: { _ in 0 }), 3)
|
|
XCTAssertEqual(mock.withMultClosures(closure: { _ in 0 }, closureB: { _ in 1 }, closureC: { _ in 2 }), 4)
|
|
XCTAssertEqual(mock.withThrowingClosure { p throws in
|
|
return nil
|
|
}, "throwing closure")
|
|
XCTAssertEqual(try! mock.withThrowingClosureThrows(closure: { _ in nil }), "closure throwing")
|
|
XCTAssertEqual(mock.withThrowingEscapingClosure(closure: { _ in nil }), "escaping closure")
|
|
XCTAssertEqual(try! mock.withThrowingOptionalClosureThrows(closure: { _ in nil }), "optional closure throwing")
|
|
XCTAssertEqual(mock.methodWithParameter("a"), "parameter string")
|
|
XCTAssertEqual(mock.methodWithParameter(1), "parameter int")
|
|
|
|
// class
|
|
XCTAssertEqual(mock.privateSetProperty, 5)
|
|
XCTAssertEqual(mock.readOnlyProperty, "b")
|
|
XCTAssertEqual({
|
|
mock.readWriteProperty = 100
|
|
return setReadWriteProperty
|
|
}(), 100)
|
|
XCTAssertEqual(mock.readWriteProperty, 7)
|
|
XCTAssertEqual({
|
|
mock.optionalProperty = 200
|
|
return setOptionalProperty
|
|
}(), 200)
|
|
XCTAssertEqual(mock.optionalProperty, 8)
|
|
XCTAssertTrue({
|
|
mock.noReturn()
|
|
return callNoReturn
|
|
}())
|
|
XCTAssertEqual(mock.count(characters: "a"), 9)
|
|
XCTAssertTrue({
|
|
try! mock.withNoReturnThrows()
|
|
return callNoReturnThrows
|
|
}())
|
|
XCTAssertEqual(mock.withClosure { _ in
|
|
41
|
|
}, 14)
|
|
XCTAssertTrue({
|
|
mock.withEscape("a") { _ in }
|
|
return callWithEscape
|
|
}())
|
|
XCTAssertTrue({
|
|
mock.withOptionalClosure("a") { _ in }
|
|
return callWithOptionalClosure
|
|
}())
|
|
XCTAssertTrue({
|
|
mock.withLabelAndUnderscore(labelA: "labelA", "any")
|
|
return callWithLabelAndUnderscore
|
|
}())
|
|
XCTAssertEqual(mock.callingCountCharactersMethodWithHello(), 15)
|
|
|
|
// Protocol
|
|
XCTAssertEqual(mock.protocolMethod(), "protocol method")
|
|
|
|
//
|
|
// Test Verification
|
|
// sub-sub class
|
|
verify(mock, times(1)).subSubMethod()
|
|
|
|
// sub-class
|
|
verify(mock, times(1)).withImplicitlyUnwrappedOptional(i: anyInt())
|
|
verify(mock, times(1)).withThrows()
|
|
verify(mock, times(1)).withNamedTuple(tuple: any())
|
|
verify(mock, times(1)).subclassMethod()
|
|
// verify(mock, times(1)).withOptionalClosureAndReturn(anyString(), closure: isNil())
|
|
verify(mock, times(1)).withClosureAndParam(anyString(), closure: anyClosure())
|
|
verify(mock, times(1)).withMultClosures(closure: anyClosure(), closureB: anyClosure(), closureC: anyClosure())
|
|
verify(mock, times(1)).withThrowingClosure(closure: anyThrowingClosure())
|
|
verify(mock, times(1)).withThrowingClosureThrows(closure: anyThrowingClosure())
|
|
verify(mock, times(1)).withThrowingEscapingClosure(closure: anyThrowingClosure())
|
|
// verify(mock, times(1)).withThrowingOptionalClosureThrows(closure: anyOptionalThrowingClosure())
|
|
verify(mock, times(1)).methodWithParameter(anyString())
|
|
verify(mock, times(1)).methodWithParameter(anyInt())
|
|
|
|
// class
|
|
verify(mock, times(1)).privateSetProperty.get
|
|
verify(mock, times(1)).readOnlyProperty.get
|
|
verify(mock, times(1)).readWriteProperty.set(anyInt())
|
|
verify(mock, times(1)).readWriteProperty.get
|
|
verify(mock, times(1)).optionalProperty.set(anyInt())
|
|
verify(mock, times(1)).optionalProperty.get
|
|
verify(mock, times(1)).noReturn()
|
|
verify(mock, times(1)).count(characters: anyString())
|
|
verify(mock, times(1)).withNoReturnThrows()
|
|
verify(mock, times(1)).withClosure(anyClosure())
|
|
verify(mock, times(1)).withEscape(anyString(), action: anyClosure())
|
|
verify(mock, times(1)).withOptionalClosure(anyString(), closure: anyClosure())
|
|
verify(mock, times(1)).withLabelAndUnderscore(labelA: anyString(), anyString())
|
|
verify(mock, times(1)).callingCountCharactersMethodWithHello()
|
|
|
|
// protocol
|
|
verify(mock, times(1)).protocolMethod()
|
|
}
|
|
|
|
func testSubProtocolMethod() {
|
|
let mock = MockTestedSubProtocol()
|
|
|
|
XCTAssertNotNil(mock)
|
|
|
|
let invocationExpectation = expectation(description: "function is called")
|
|
stub(mock) { mock in
|
|
when(mock.noReturnSub()).then {
|
|
invocationExpectation.fulfill()
|
|
}
|
|
}
|
|
|
|
mock.noReturnSub()
|
|
waitForExpectations(timeout: 0.1, handler: nil)
|
|
}
|
|
}
|