Added ParameterMatcher for (optional) throwing closures and optionals, e.g. anyThrowingClosure(), anyOptionalThrowingClosure and null()
Added Acceptance test for inheritance stubbing and verifying
This commit is contained in:
parent
f0f31bd0e9
commit
eaab7db26d
|
@ -45,6 +45,10 @@ public func anyString() -> ParameterMatcher<String> {
|
|||
}
|
||||
|
||||
/// Returns a matcher matching any closure.
|
||||
public func anyThrowingClosure<IN, OUT>() -> ParameterMatcher<(IN) throws -> OUT> {
|
||||
return ParameterMatcher()
|
||||
}
|
||||
|
||||
public func anyClosure<IN, OUT>() -> ParameterMatcher<(IN) -> OUT> {
|
||||
return ParameterMatcher()
|
||||
}
|
||||
|
@ -97,9 +101,28 @@ public func anyClosure<IN, OUT>() -> ParameterMatcher<(((IN)) -> OUT)?> {
|
|||
return notNil()
|
||||
}
|
||||
|
||||
public func anyOptionalThrowingClosure<IN, OUT>() -> ParameterMatcher<(((IN)) throws -> OUT)?> {
|
||||
return notNil()
|
||||
}
|
||||
|
||||
/// Returns a matcher matching any non nil value.
|
||||
public func notNil<T>() -> ParameterMatcher<T?> {
|
||||
return ParameterMatcher {
|
||||
if case .none = $0 { return false } else { return true }
|
||||
if case .none = $0 {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a matcher matching any nil value
|
||||
public func isNil<T>() -> ParameterMatcher<T?> {
|
||||
return ParameterMatcher {
|
||||
if case .none = $0 {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -55,10 +55,27 @@ class ParameterMatcherFunctionsTest: XCTestCase {
|
|||
XCTAssertTrue(any().matches(X()))
|
||||
}
|
||||
|
||||
func testIsNil() {
|
||||
let optional: X? = nil
|
||||
XCTAssertTrue(isNil().matches(nil as X?))
|
||||
XCTAssertTrue(isNil().matches(optional))
|
||||
XCTAssertFalse(isNil().matches(X()))
|
||||
}
|
||||
|
||||
func testAnyClosure() {
|
||||
XCTAssertTrue(anyClosure().matches({ 0 }))
|
||||
}
|
||||
|
||||
func testAnyThrowingClosure() {
|
||||
XCTAssertTrue(anyThrowingClosure().matches({ 0 }))
|
||||
XCTAssertTrue(anyThrowingClosure().matches({ (p: Int) throws in 1 }))
|
||||
}
|
||||
|
||||
func testAnyOptionalThrowingClosure() {
|
||||
XCTAssertTrue(anyOptionalThrowingClosure().matches({ (i: String) in 0 }))
|
||||
XCTAssertTrue(anyOptionalThrowingClosure().matches({ (p: Int) throws in 1 }))
|
||||
}
|
||||
|
||||
func testOptionalEqualToEquatable() {
|
||||
XCTAssertTrue(equal(to: nil as Int?).matches(nil))
|
||||
XCTAssertTrue(equal(to: 1 as Int?).matches(1))
|
||||
|
|
|
@ -56,19 +56,19 @@ class TestedSubclass: TestedClass, TestedProtocol {
|
|||
return 0
|
||||
}
|
||||
|
||||
func withThrowingClosure(closure: ((String)) throws -> String?) -> String? {
|
||||
func withThrowingClosure(closure: (String) throws -> String?) -> String? {
|
||||
return nil
|
||||
}
|
||||
|
||||
func withThrowingClosureThrows(closure: ((String)) throws -> String?) throws -> String? {
|
||||
func withThrowingClosureThrows(closure: (String) throws -> String?) throws -> String? {
|
||||
return nil
|
||||
}
|
||||
|
||||
func withThrowingEscapingClosure(closure: @escaping ((String)) throws -> String?) -> String? {
|
||||
func withThrowingEscapingClosure(closure: @escaping (String) throws -> String?) -> String? {
|
||||
return nil
|
||||
}
|
||||
|
||||
func withThrowingOptionalClosureThrows(closure: (((String)) throws -> String?)?) throws -> String? {
|
||||
func withThrowingOptionalClosureThrows(closure: ((String) throws -> String?)?) throws -> String? {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -80,3 +80,11 @@ class TestedSubclass: TestedClass, TestedProtocol {
|
|||
return "c"
|
||||
}
|
||||
}
|
||||
|
||||
class TestedSubSubClass: TestedSubclass {
|
||||
|
||||
func subSubMethod() -> String? {
|
||||
return nil
|
||||
}
|
||||
|
||||
}
|
|
@ -93,6 +93,7 @@ class StubbingTest: XCTestCase {
|
|||
XCTAssertNotNil(mock)
|
||||
|
||||
stub(mock) { mock in
|
||||
when(mock.methodWithParameter(anyInt())).thenReturn("t1")
|
||||
when(mock.methodWithParameter(anyString())).thenReturn("t")
|
||||
}
|
||||
|
||||
|
@ -106,6 +107,7 @@ class StubbingTest: XCTestCase {
|
|||
|
||||
stub(mock) { mock in
|
||||
when(mock.methodWithParameter(anyInt())).thenReturn("t1")
|
||||
when(mock.methodWithParameter(anyString())).thenReturn("s1")
|
||||
}
|
||||
|
||||
XCTAssertEqual(mock.methodWithParameter(1), "t1")
|
||||
|
@ -123,4 +125,174 @@ class StubbingTest: XCTestCase {
|
|||
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue