Refactor fail description.
This commit is contained in:
parent
97d56e0b6a
commit
39b233b766
|
@ -10,6 +10,7 @@
|
||||||
183D03FF1C4691C600EBAEF3 /* Cuckoo.h in Headers */ = {isa = PBXBuildFile; fileRef = 183D03FE1C4691C600EBAEF3 /* Cuckoo.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
183D03FF1C4691C600EBAEF3 /* Cuckoo.h in Headers */ = {isa = PBXBuildFile; fileRef = 183D03FE1C4691C600EBAEF3 /* Cuckoo.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
183D04061C4691C600EBAEF3 /* Cuckoo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 183D03FB1C4691C600EBAEF3 /* Cuckoo.framework */; };
|
183D04061C4691C600EBAEF3 /* Cuckoo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 183D03FB1C4691C600EBAEF3 /* Cuckoo.framework */; };
|
||||||
183D04161C46926A00EBAEF3 /* CuckooFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 183D04151C46926A00EBAEF3 /* CuckooFunctions.swift */; };
|
183D04161C46926A00EBAEF3 /* CuckooFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 183D04151C46926A00EBAEF3 /* CuckooFunctions.swift */; };
|
||||||
|
DC1A82B51D2D6BD500A217F0 /* FailTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC1A82B31D2D6A2100A217F0 /* FailTest.swift */; };
|
||||||
DC4094EE1D211563006FB137 /* StubFunction.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC4094EC1D211563006FB137 /* StubFunction.swift */; };
|
DC4094EE1D211563006FB137 /* StubFunction.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC4094EC1D211563006FB137 /* StubFunction.swift */; };
|
||||||
DC4094EF1D211563006FB137 /* StubThrowingFunction.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC4094ED1D211563006FB137 /* StubThrowingFunction.swift */; };
|
DC4094EF1D211563006FB137 /* StubThrowingFunction.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC4094ED1D211563006FB137 /* StubThrowingFunction.swift */; };
|
||||||
DC4094F31D211598006FB137 /* ToBeStubbedProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC4094F11D211598006FB137 /* ToBeStubbedProperty.swift */; };
|
DC4094F31D211598006FB137 /* ToBeStubbedProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC4094F11D211598006FB137 /* ToBeStubbedProperty.swift */; };
|
||||||
|
@ -82,6 +83,7 @@
|
||||||
183D04051C4691C600EBAEF3 /* CuckooTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CuckooTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
183D04051C4691C600EBAEF3 /* CuckooTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CuckooTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
183D040C1C4691C600EBAEF3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
183D040C1C4691C600EBAEF3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||||
183D04151C46926A00EBAEF3 /* CuckooFunctions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CuckooFunctions.swift; sourceTree = "<group>"; };
|
183D04151C46926A00EBAEF3 /* CuckooFunctions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CuckooFunctions.swift; sourceTree = "<group>"; };
|
||||||
|
DC1A82B31D2D6A2100A217F0 /* FailTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = FailTest.swift; path = ../../../Brightify/Cuckoo/Tests/FailTest.swift; sourceTree = "<group>"; };
|
||||||
DC4094EC1D211563006FB137 /* StubFunction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = StubFunction.swift; path = Stubbing/StubFunction/StubFunction.swift; sourceTree = "<group>"; };
|
DC4094EC1D211563006FB137 /* StubFunction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = StubFunction.swift; path = Stubbing/StubFunction/StubFunction.swift; sourceTree = "<group>"; };
|
||||||
DC4094ED1D211563006FB137 /* StubThrowingFunction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = StubThrowingFunction.swift; path = Stubbing/StubFunction/StubThrowingFunction.swift; sourceTree = "<group>"; };
|
DC4094ED1D211563006FB137 /* StubThrowingFunction.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = StubThrowingFunction.swift; path = Stubbing/StubFunction/StubThrowingFunction.swift; sourceTree = "<group>"; };
|
||||||
DC4094F11D211598006FB137 /* ToBeStubbedProperty.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ToBeStubbedProperty.swift; path = Stubbing/ToBeStubbedProperty/ToBeStubbedProperty.swift; sourceTree = "<group>"; };
|
DC4094F11D211598006FB137 /* ToBeStubbedProperty.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ToBeStubbedProperty.swift; path = Stubbing/ToBeStubbedProperty/ToBeStubbedProperty.swift; sourceTree = "<group>"; };
|
||||||
|
@ -198,6 +200,7 @@
|
||||||
183D040C1C4691C600EBAEF3 /* Info.plist */,
|
183D040C1C4691C600EBAEF3 /* Info.plist */,
|
||||||
DC70D0A91D2AB5F500014C5F /* ClassTest.swift */,
|
DC70D0A91D2AB5F500014C5F /* ClassTest.swift */,
|
||||||
DC70D0A61D2AB5B300014C5F /* CuckooFunctionsTest.swift */,
|
DC70D0A61D2AB5B300014C5F /* CuckooFunctionsTest.swift */,
|
||||||
|
DC1A82B31D2D6A2100A217F0 /* FailTest.swift */,
|
||||||
DC70D0AC1D2AB62100014C5F /* ProtocolTest.swift */,
|
DC70D0AC1D2AB62100014C5F /* ProtocolTest.swift */,
|
||||||
DC70D0B71D2ABA3100014C5F /* TestUtils.swift */,
|
DC70D0B71D2ABA3100014C5F /* TestUtils.swift */,
|
||||||
DC70D0A01D2AB53D00014C5F /* Describing */,
|
DC70D0A01D2AB53D00014C5F /* Describing */,
|
||||||
|
@ -547,6 +550,7 @@
|
||||||
DC70D0B31D2AB6B900014C5F /* MatchableTest.swift in Sources */,
|
DC70D0B31D2AB6B900014C5F /* MatchableTest.swift in Sources */,
|
||||||
DC70D0BE1D2AF40800014C5F /* TestedClass.swift in Sources */,
|
DC70D0BE1D2AF40800014C5F /* TestedClass.swift in Sources */,
|
||||||
DC70D0D21D2B007300014C5F /* GeneratedMocks.swift in Sources */,
|
DC70D0D21D2B007300014C5F /* GeneratedMocks.swift in Sources */,
|
||||||
|
DC1A82B51D2D6BD500A217F0 /* FailTest.swift in Sources */,
|
||||||
DC70D0D41D2B026200014C5F /* VerificationTest.swift in Sources */,
|
DC70D0D41D2B026200014C5F /* VerificationTest.swift in Sources */,
|
||||||
DC70D0AD1D2AB62100014C5F /* ProtocolTest.swift in Sources */,
|
DC70D0AD1D2AB62100014C5F /* ProtocolTest.swift in Sources */,
|
||||||
DC70D0C51D2AFA8E00014C5F /* StubFunctionTest.swift in Sources */,
|
DC70D0C51D2AFA8E00014C5F /* StubFunctionTest.swift in Sources */,
|
||||||
|
|
|
@ -19,8 +19,8 @@ public func when<F>(function: F) -> F {
|
||||||
|
|
||||||
/// Creates object used for verification of calls.
|
/// Creates object used for verification of calls.
|
||||||
@warn_unused_result
|
@warn_unused_result
|
||||||
public func verify<M: Mock>(mock: M, _ callMatcher: CallMatcher = times(1), sourceLocation: SourceLocation = (#file, #line)) -> M.Verification {
|
public func verify<M: Mock>(mock: M, _ callMatcher: CallMatcher = times(1), file: StaticString = #file, line: UInt = #line) -> M.Verification {
|
||||||
return mock.getVerificationProxy(callMatcher, sourceLocation: sourceLocation)
|
return mock.getVerificationProxy(callMatcher, sourceLocation: (file, line))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clears all invocations and stubs of mocks.
|
/// Clears all invocations and stubs of mocks.
|
||||||
|
@ -45,8 +45,8 @@ public func clearInvocations<M: Mock>(mocks: M...) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Checks if there are no more uverified calls.
|
/// Checks if there are no more uverified calls.
|
||||||
public func verifyNoMoreInteractions<M: Mock>(mocks: M..., sourceLocation: SourceLocation = (#file, #line)) {
|
public func verifyNoMoreInteractions<M: Mock>(mocks: M..., file: StaticString = #file, line: UInt = #line) {
|
||||||
mocks.forEach { mock in
|
mocks.forEach { mock in
|
||||||
mock.manager.verifyNoMoreInteractions(sourceLocation)
|
mock.manager.verifyNoMoreInteractions((file, line))
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -8,34 +8,35 @@
|
||||||
|
|
||||||
/// CallMatcher is used in verification to assert how many times was the call made. It can also be used to do different asserts on stub calls matched with parameter matchers.
|
/// CallMatcher is used in verification to assert how many times was the call made. It can also be used to do different asserts on stub calls matched with parameter matchers.
|
||||||
public struct CallMatcher {
|
public struct CallMatcher {
|
||||||
private let matchesFunction: [StubCall] throws -> Bool
|
public let name: String
|
||||||
|
|
||||||
public init(matchesFunction: [StubCall] -> Bool = { _ in true }) {
|
private let matchesFunction: [StubCall] -> Bool
|
||||||
|
|
||||||
|
public init(name: String, matchesFunction: [StubCall] -> Bool) {
|
||||||
|
self.name = name
|
||||||
self.matchesFunction = matchesFunction
|
self.matchesFunction = matchesFunction
|
||||||
}
|
}
|
||||||
|
|
||||||
public init(numberOfExpectedCalls: Int, compareCallsFunction: (expected: Int, actual: Int) -> Bool) {
|
public init(name: String, numberOfExpectedCalls: Int, compareCallsFunction: (expected: Int, actual: Int) -> Bool) {
|
||||||
self.matchesFunction = {
|
self.init(name: name) {
|
||||||
return compareCallsFunction(expected: numberOfExpectedCalls, actual: $0.count)
|
return compareCallsFunction(expected: numberOfExpectedCalls, actual: $0.count)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func matches(calls: [StubCall]) -> Bool {
|
public func matches(calls: [StubCall]) -> Bool {
|
||||||
do {
|
return matchesFunction(calls)
|
||||||
return try matchesFunction(calls)
|
|
||||||
} catch {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public func or(otherMatcher: CallMatcher) -> CallMatcher {
|
public func or(otherMatcher: CallMatcher) -> CallMatcher {
|
||||||
return CallMatcher {
|
let name = "either \(self.name) or \(otherMatcher.name)"
|
||||||
|
return CallMatcher(name: name) {
|
||||||
return self.matches($0) || otherMatcher.matches($0)
|
return self.matches($0) || otherMatcher.matches($0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func and(otherMatcher: CallMatcher) -> CallMatcher {
|
public func and(otherMatcher: CallMatcher) -> CallMatcher {
|
||||||
return CallMatcher {
|
let name = "both \(self.name) and \(otherMatcher.name)"
|
||||||
|
return CallMatcher(name: name) {
|
||||||
return self.matches($0) && otherMatcher.matches($0)
|
return self.matches($0) && otherMatcher.matches($0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,8 @@
|
||||||
/// Returns a matcher ensuring a call was made **`count`** times.
|
/// Returns a matcher ensuring a call was made **`count`** times.
|
||||||
@warn_unused_result
|
@warn_unused_result
|
||||||
public func times(count: Int) -> CallMatcher {
|
public func times(count: Int) -> CallMatcher {
|
||||||
return CallMatcher(numberOfExpectedCalls: count, compareCallsFunction: ==)
|
let name = count == 0 ? "never" : "\(count) times"
|
||||||
|
return CallMatcher(name: name, numberOfExpectedCalls: count, compareCallsFunction: ==)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a matcher ensuring no call was made.
|
/// Returns a matcher ensuring no call was made.
|
||||||
|
@ -27,11 +28,11 @@ public func atLeastOnce() -> CallMatcher {
|
||||||
/// Returns a matcher ensuring call was made at least `count` times.
|
/// Returns a matcher ensuring call was made at least `count` times.
|
||||||
@warn_unused_result
|
@warn_unused_result
|
||||||
public func atLeast(count: Int) -> CallMatcher {
|
public func atLeast(count: Int) -> CallMatcher {
|
||||||
return CallMatcher(numberOfExpectedCalls: count, compareCallsFunction: <=)
|
return CallMatcher(name: "at least \(count) times", numberOfExpectedCalls: count, compareCallsFunction: <=)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a matcher ensuring call was made at most `count` times.
|
/// Returns a matcher ensuring call was made at most `count` times.
|
||||||
@warn_unused_result
|
@warn_unused_result
|
||||||
public func atMost(count: Int) -> CallMatcher {
|
public func atMost(count: Int) -> CallMatcher {
|
||||||
return CallMatcher(numberOfExpectedCalls: count, compareCallsFunction: >=)
|
return CallMatcher(name: "at most \(count) times",numberOfExpectedCalls: count, compareCallsFunction: >=)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
/// ParameterMatcher matches parameters of methods in stubbing and verification.
|
/// ParameterMatcher matches parameters of methods in stubbing and verification.
|
||||||
public struct ParameterMatcher<T>: Matchable {
|
public struct ParameterMatcher<T>: Matchable {
|
||||||
private let matchesFunction: T throws -> Bool
|
private let matchesFunction: T -> Bool
|
||||||
|
|
||||||
public init(matchesFunction: T -> Bool = { _ in true }) {
|
public init(matchesFunction: T -> Bool = { _ in true }) {
|
||||||
self.matchesFunction = matchesFunction
|
self.matchesFunction = matchesFunction
|
||||||
|
@ -19,10 +19,6 @@ public struct ParameterMatcher<T>: Matchable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public func matches(input: T) -> Bool {
|
public func matches(input: T) -> Bool {
|
||||||
do {
|
return matchesFunction(input)
|
||||||
return try matchesFunction(input)
|
|
||||||
} catch {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -84,8 +84,8 @@ public class MockManager {
|
||||||
unverifiedStubCallsIndexes = unverifiedStubCallsIndexes.filter { !indexesToRemove.contains($0) }
|
unverifiedStubCallsIndexes = unverifiedStubCallsIndexes.filter { !indexesToRemove.contains($0) }
|
||||||
|
|
||||||
if callMatcher.matches(calls) == false {
|
if callMatcher.matches(calls) == false {
|
||||||
let description = Description()
|
let message = "Wanted \(callMatcher.name) but \(calls.count == 0 ? "not invoked" : "invoked \(calls.count) times")."
|
||||||
MockManager.fail(message: description.description, sourceLocation: sourceLocation)
|
MockManager.fail(message: message, sourceLocation: sourceLocation)
|
||||||
}
|
}
|
||||||
return __DoNotUse()
|
return __DoNotUse()
|
||||||
}
|
}
|
||||||
|
@ -106,14 +106,26 @@ public class MockManager {
|
||||||
|
|
||||||
func verifyNoMoreInteractions(sourceLocation: SourceLocation) {
|
func verifyNoMoreInteractions(sourceLocation: SourceLocation) {
|
||||||
if unverifiedStubCallsIndexes.isEmpty == false {
|
if unverifiedStubCallsIndexes.isEmpty == false {
|
||||||
let unverifiedCalls = unverifiedStubCallsIndexes.map { stubCalls[$0] }.map { String($0) }.joinWithSeparator(", ")
|
let unverifiedCalls = unverifiedStubCallsIndexes.map { stubCalls[$0] }.map { call in
|
||||||
MockManager.fail(message: "Found unverified call(s): " + unverifiedCalls, sourceLocation: sourceLocation)
|
if let bracketIndex = call.method.rangeOfString("(")?.startIndex {
|
||||||
|
let name = call.method.substringToIndex(bracketIndex)
|
||||||
|
return name + call.parametersAsString
|
||||||
|
} else {
|
||||||
|
if call.method.hasSuffix("#set") {
|
||||||
|
return call.method + call.parametersAsString
|
||||||
|
} else {
|
||||||
|
return call.method
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.enumerate().map { "\($0 + 1). " + $1 }.joinWithSeparator("\n")
|
||||||
|
let message = "No more interactions wanted but some found:\n"
|
||||||
|
MockManager.fail(message: message + unverifiedCalls, sourceLocation: sourceLocation)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@noreturn
|
@noreturn
|
||||||
private func failAndCrash(message: String, sourceLocation: SourceLocation = (#file, #line)) {
|
private func failAndCrash(message: String, file: StaticString = #file, line: UInt = #line) {
|
||||||
MockManager.fail(message: message, sourceLocation: sourceLocation)
|
MockManager.fail(message: message, sourceLocation: (file, line))
|
||||||
fatalError(message)
|
fatalError(message)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,11 +8,23 @@
|
||||||
|
|
||||||
public protocol StubCall {
|
public protocol StubCall {
|
||||||
var method: String { get }
|
var method: String { get }
|
||||||
|
var parametersAsString: String { get }
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct ConcreteStubCall<IN>: StubCall {
|
public struct ConcreteStubCall<IN>: StubCall {
|
||||||
public let method: String
|
public let method: String
|
||||||
let parameters: IN
|
public let parameters: IN
|
||||||
|
|
||||||
|
public var parametersAsString: String {
|
||||||
|
let string = String(parameters)
|
||||||
|
if (string.rangeOfString(",") != nil && string.hasPrefix("(")) || string == "()" {
|
||||||
|
return string
|
||||||
|
} else {
|
||||||
|
// If only one parameter add brackets and quotes
|
||||||
|
let wrappedParameter = String((parameters, 0))
|
||||||
|
return wrappedParameter.substringToIndex(wrappedParameter.endIndex.advancedBy(-4)) + ")"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public init(method: String, parameters: IN) {
|
public init(method: String, parameters: IN) {
|
||||||
self.method = method
|
self.method = method
|
||||||
|
|
|
@ -64,19 +64,4 @@ class CuckooFunctionsTest: XCTestCase {
|
||||||
|
|
||||||
verifyNoMoreInteractions(mock)
|
verifyNoMoreInteractions(mock)
|
||||||
}
|
}
|
||||||
|
|
||||||
func testVerifyNoMoreInteractionsFail() {
|
|
||||||
let error = TestUtils.catchCuckooFail {
|
|
||||||
let mock = MockTestedClass()
|
|
||||||
stub(mock) { mock in
|
|
||||||
when(mock.noReturn()).thenDoNothing()
|
|
||||||
}
|
|
||||||
|
|
||||||
mock.noReturn()
|
|
||||||
|
|
||||||
verifyNoMoreInteractions(mock)
|
|
||||||
}
|
|
||||||
|
|
||||||
XCTAssertNotNil(error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,133 @@
|
||||||
|
//
|
||||||
|
// FailTest.swift
|
||||||
|
// Cuckoo
|
||||||
|
//
|
||||||
|
// Created by Filip Dolnik on 06.07.16.
|
||||||
|
// Copyright © 2016 Brightify. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
import Cuckoo
|
||||||
|
|
||||||
|
class FailTest: XCTestCase {
|
||||||
|
|
||||||
|
func testMissingInvocation() {
|
||||||
|
let error = TestUtils.catchCuckooFail {
|
||||||
|
let mock = MockTestedClass()
|
||||||
|
|
||||||
|
verify(mock).noReturn()
|
||||||
|
}
|
||||||
|
|
||||||
|
XCTAssertEqual(error, "Wanted 1 times but not invoked.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testNoInvocation2Wanted() {
|
||||||
|
let error = TestUtils.catchCuckooFail {
|
||||||
|
let mock = MockTestedClass()
|
||||||
|
stub(mock) { mock in
|
||||||
|
when(mock.noReturn()).thenDoNothing()
|
||||||
|
}
|
||||||
|
|
||||||
|
mock.noReturn()
|
||||||
|
|
||||||
|
verify(mock, times(2)).noReturn()
|
||||||
|
}
|
||||||
|
|
||||||
|
XCTAssertEqual(error, "Wanted 2 times but invoked 1 times.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testInvocationNeverWanted() {
|
||||||
|
let error = TestUtils.catchCuckooFail {
|
||||||
|
let mock = MockTestedClass()
|
||||||
|
stub(mock) { mock in
|
||||||
|
when(mock.noReturn()).thenDoNothing()
|
||||||
|
}
|
||||||
|
|
||||||
|
mock.noReturn()
|
||||||
|
|
||||||
|
verify(mock, never()).noReturn()
|
||||||
|
}
|
||||||
|
|
||||||
|
XCTAssertEqual(error, "Wanted never but invoked 1 times.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testInvocationAtLeast2Wanted() {
|
||||||
|
let error = TestUtils.catchCuckooFail {
|
||||||
|
let mock = MockTestedClass()
|
||||||
|
stub(mock) { mock in
|
||||||
|
when(mock.noReturn()).thenDoNothing()
|
||||||
|
}
|
||||||
|
|
||||||
|
mock.noReturn()
|
||||||
|
|
||||||
|
verify(mock, atLeast(2)).noReturn()
|
||||||
|
}
|
||||||
|
|
||||||
|
XCTAssertEqual(error, "Wanted at least 2 times but invoked 1 times.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func test2InvocationAtMost1Wanted() {
|
||||||
|
let error = TestUtils.catchCuckooFail {
|
||||||
|
let mock = MockTestedClass()
|
||||||
|
stub(mock) { mock in
|
||||||
|
when(mock.noReturn()).thenDoNothing()
|
||||||
|
}
|
||||||
|
|
||||||
|
mock.noReturn()
|
||||||
|
mock.noReturn()
|
||||||
|
|
||||||
|
verify(mock, atMost(1)).noReturn()
|
||||||
|
}
|
||||||
|
|
||||||
|
XCTAssertEqual(error, "Wanted at most 1 times but invoked 2 times.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testCallMatcherOr() {
|
||||||
|
let error = TestUtils.catchCuckooFail {
|
||||||
|
let mock = MockTestedClass()
|
||||||
|
stub(mock) { mock in
|
||||||
|
when(mock.noReturn()).thenDoNothing()
|
||||||
|
}
|
||||||
|
|
||||||
|
verify(mock, times(1).or(times(2))).noReturn()
|
||||||
|
}
|
||||||
|
|
||||||
|
XCTAssertEqual(error, "Wanted either 1 times or 2 times but not invoked.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testCallMatcherAnd() {
|
||||||
|
let error = TestUtils.catchCuckooFail {
|
||||||
|
let mock = MockTestedClass()
|
||||||
|
stub(mock) { mock in
|
||||||
|
when(mock.noReturn()).thenDoNothing()
|
||||||
|
}
|
||||||
|
|
||||||
|
verify(mock, atLeast(1).and(atMost(2))).noReturn()
|
||||||
|
}
|
||||||
|
|
||||||
|
XCTAssertEqual(error, "Wanted both at least 1 times and at most 2 times but not invoked.")
|
||||||
|
}
|
||||||
|
|
||||||
|
func testVerifyNoMoreInteractionsFail() {
|
||||||
|
let error = TestUtils.catchCuckooFail {
|
||||||
|
let mock = MockTestedClass(spyOn: TestedClass())
|
||||||
|
|
||||||
|
mock.withOptionalClosure("a", closure: nil)
|
||||||
|
mock.noReturn()
|
||||||
|
mock.countCharacters("b")
|
||||||
|
let _ = mock.readWriteProperty
|
||||||
|
mock.readWriteProperty = 1
|
||||||
|
mock.withOptionalClosure("c", closure: { _ in })
|
||||||
|
|
||||||
|
verifyNoMoreInteractions(mock)
|
||||||
|
}
|
||||||
|
|
||||||
|
XCTAssertEqual(error, "No more interactions wanted but some found:\n" +
|
||||||
|
"1. withOptionalClosure(\"a\", nil)\n" +
|
||||||
|
"2. noReturn()\n" +
|
||||||
|
"3. countCharacters(\"b\")\n" +
|
||||||
|
"4. readWriteProperty#get\n" +
|
||||||
|
"5. readWriteProperty#set(1)\n" +
|
||||||
|
"6. withOptionalClosure(\"c\", Optional((Function)))")
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,7 +17,7 @@ class CallMatcherTest: XCTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
func testMatches() {
|
func testMatches() {
|
||||||
let matcher = CallMatcher { ($0.first?.method ?? "") == "A"}
|
let matcher = CallMatcher(name: "") { ($0.first?.method ?? "") == "A"}
|
||||||
let nonMatchingCalls = [ConcreteStubCall(method: "B", parameters: Void()) as StubCall]
|
let nonMatchingCalls = [ConcreteStubCall(method: "B", parameters: Void()) as StubCall]
|
||||||
|
|
||||||
XCTAssertTrue(matcher.matches(call))
|
XCTAssertTrue(matcher.matches(call))
|
||||||
|
|
|
@ -47,14 +47,4 @@ class VerificationTest: XCTestCase {
|
||||||
verify(mock).noReturn()
|
verify(mock).noReturn()
|
||||||
verify(mock).countCharacters(anyString())
|
verify(mock).countCharacters(anyString())
|
||||||
}
|
}
|
||||||
|
|
||||||
func testVerifyFail() {
|
|
||||||
let error = TestUtils.catchCuckooFail {
|
|
||||||
let mock = MockTestedClass()
|
|
||||||
|
|
||||||
verify(mock).noReturn()
|
|
||||||
}
|
|
||||||
|
|
||||||
XCTAssertNotNil(error)
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue