我有这样的设想:
class X {
init(y: ProtocolA)
func foo(){
if(y.isSomething()){
methodA()
} else {
methodB()
}
}
func methodA(){
// any
}
func methodB(){
// any
}
}
class Y : ProtocolA {
func isSomething(): Bool { return true OR false }
}我想测试X级,
我将在两个不同的测试中模拟ProtocolA返回isSomething()方法true或false,以了解是否调用了methodA或methodB。
解决这个问题的最佳策略是什么?
ps:使用mockito,使用Spy和,这非常容易,但是使用Swift非常痛苦
编辑:
好吧,我这么做:
第一,各部分:
class X { init(y: Y) }
protocol Y { func isSomething() -> Bool }现在,用于测试的结构:模拟和间谍对象。
typealias VerifyMethodAssert = (count: Int, parameters: [Any]?, returnn: Any?)用于依赖关系的可配置锁
class YMock : Y {
init(configure: Bool)
func isSomething{ return configure }
}混凝土级间谍
class XSpy : X {
private let y: Y
var verify: [String: VerifyMethodAssert] = [
"methodA()": (count: 0, parameters: nil, returnn: nil)
"methodB()": (count: 0, parameters: nil, returnn: nil)
]
var nothing: [String: Bool] = [
"methodA()": false
"methodB()": false
]
init(y: Y, verify: [String: VerifyMethodAssert]?, nothing: [String: Bool]?)
func methodA(){
verify["\(#function)"] = (count: verify["\(#function)"]!.count + 1, parameters: nil,
returnn: nothing["\(#function)"]! ? nil : super.methodA())
}
func methodB(doNothing: Bool = false){
verify["\(#function)"] = (count: verify["\(#function)"]!.count + 1, parameters: nil,
returnn: nothing["\(#function)"]! ? nil : super.methodB())
}
}和测试:
class XTest : QuickSpec {
override func spec(){
describe("a position view model"){
it("test 1"){
let y = Y(configure: true)
let x = XSpy(y: y)
x.foo()
expect(1).to(x.verify["methodA()"].count)
expect(0).to(x.verify["methodB()"].count)
}
it("test 2"){
let y = Y(configure: true)
let x = XSpy(y: y)
x.foo()
expect(0).to(x.verify["methodA()"].count)
expect(1).to(x.verify["methodB()"].count)
}
}
}
}发布于 2018-08-29 17:10:57
据我所知,没有开箱即用的方式。这样做的一种方法是检查柜台:
class X {
var countA: Int = 0
var countB: Int = 0
init(y: ProtocolA)
func foo(){
if(y.isSomething()){
methodA()
} else {
methodB()
}
}
func methodA(){
countA += 1
// any
}
func methodB(){
countB += 1
// any
}
}这种方法也被建议为这里。
发布于 2018-08-29 21:48:07
在这种特殊情况下,您可以子类X并使用关联对象来保存调用计数,如果您看到自己一次又一次地使用它,则可以泛化它:
final class TestX: X {
private struct AssociatedKeys {
static var invocations = "\(String(describing: type(of: TestX.self)))-invocations"
}
func invocations(for method: String) -> Int {
return invocations[method] ?? 0
}
private var invocations: [String: Int] {
get {
return objc_getAssociatedObject(self, &AssociatedKeys.invocations) as? [String: Int] ?? [:]
}
set {
objc_setAssociatedObject( self, &AssociatedKeys.invocations, newValue as NSDictionary, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
override func methodA(){
super.methodA()
invocations["methodA"] = (invocations["methodA"] ?? 0) + 1
}
override func methodB(){
super.methodB()
invocations["methodB"] = (invocations["methodB"] ?? 0) + 1
}
}
let x = TestX(y: Y())
x.invocations(for: "methodA") //0
x.foo()
x.invocations(for: "methodA") //1https://stackoverflow.com/questions/52081144
复制相似问题