Swift:baseclass的数组没有调用subclass函数实现
Swift: Array of base class does not call subclass function implementation
我正在尝试根据 SimplePing、一个 NSObject 子 class 将一个假实例注入 class 的单元测试中。我的 class 有一个 属性 var simplePings: [SimplePing]
,在我的单元测试中我将其设置为 FakeSimplePing 数组。但是,当 class 进入数组并调用 simplePing.start()
时,它会调用 SimplePing.start 实现而不是 FakeSimplePing 的实现,即使在调试时我看到实例类型是 FakeSimplePing。
当属性只是一个SimplePing时,单元测试使用FakeSimplePing.start,测试通过。这与 Swift 和 superclasses 的数组有关吗?
class Pinger : NSObject {
private var simplePings: [SimplePing] = []
func pingLocation(location: Location) -> Signal<Double, NoError> {
let simplePings = location.serverIPs.map { (serverIP: String) -> SimplePing in
let simplePing = SimplePing(hostName: serverIP)
simplePing?.delegate = self
return simplePing
}
configureDependencies(simplePings)
simplePings.forEach { [=12=].start() }
return signal
}
func configureDependencies(simplePings: [SimplePing]) {
if self.simplePings.isEmpty {
self.simplePings = simplePings
}
}
}
class FakeSimplePing: SimplePing {
var receivedStart = false
var receivedSendPingWithData = false
var fakeHostName: String!
override var hostName: String {
return fakeHostName
}
convenience init(hostName: String) {
self.init()
fakeHostName = hostName
}
override func start() {
// This does not get called
receivedStart = true
delegate?.simplePing?(self, didStartWithAddress: nil)
delegate?.simplePing?(self, didReceivePingResponsePacket: nil)
}
override func sendPingWithData(data: NSData!) {
receivedSendPingWithData = true
}
}
失败的测试:
beforeEach {
fakeSimplePing = FakeSimplePing(hostName: serverIP)
fakeSimplePing.delegate = pinger
pinger.configureDependencies([fakeSimplePing])
}
it("pings server with data") {
pinger.pingLocation(location)
expect(fakeSimplePing.receivedSendPingWithData).toEventually(beTrue())
}
问题(我相信...)在 pingLocation
中的命名中
行
let simplePings = location.serverIPs.map { ....
您使用与 属性
相同的名字
private var simplePings: [SimplePing] = []
所以你可能认为你正在用 let
定义一个新变量,但实际上,你可能只是使用你的 属性 并在途中改变它,所以它变成了 SimplePing
数组,因为它returns来自地图
尝试将您的方法更改为:
func pingLocation(location: Location) -> Signal<Double, NoError> {
let tempSimplePings = location.serverIPs.map { (serverIP: String) -> SimplePing in
let simplePing = SimplePing(hostName: serverIP)
simplePing?.delegate = self
return simplePing
}
configureDependencies(tempSimplePings)
simplePings.forEach { [=12=].start() }
return signal
}
我正在尝试根据 SimplePing、一个 NSObject 子 class 将一个假实例注入 class 的单元测试中。我的 class 有一个 属性 var simplePings: [SimplePing]
,在我的单元测试中我将其设置为 FakeSimplePing 数组。但是,当 class 进入数组并调用 simplePing.start()
时,它会调用 SimplePing.start 实现而不是 FakeSimplePing 的实现,即使在调试时我看到实例类型是 FakeSimplePing。
当属性只是一个SimplePing时,单元测试使用FakeSimplePing.start,测试通过。这与 Swift 和 superclasses 的数组有关吗?
class Pinger : NSObject {
private var simplePings: [SimplePing] = []
func pingLocation(location: Location) -> Signal<Double, NoError> {
let simplePings = location.serverIPs.map { (serverIP: String) -> SimplePing in
let simplePing = SimplePing(hostName: serverIP)
simplePing?.delegate = self
return simplePing
}
configureDependencies(simplePings)
simplePings.forEach { [=12=].start() }
return signal
}
func configureDependencies(simplePings: [SimplePing]) {
if self.simplePings.isEmpty {
self.simplePings = simplePings
}
}
}
class FakeSimplePing: SimplePing {
var receivedStart = false
var receivedSendPingWithData = false
var fakeHostName: String!
override var hostName: String {
return fakeHostName
}
convenience init(hostName: String) {
self.init()
fakeHostName = hostName
}
override func start() {
// This does not get called
receivedStart = true
delegate?.simplePing?(self, didStartWithAddress: nil)
delegate?.simplePing?(self, didReceivePingResponsePacket: nil)
}
override func sendPingWithData(data: NSData!) {
receivedSendPingWithData = true
}
}
失败的测试:
beforeEach {
fakeSimplePing = FakeSimplePing(hostName: serverIP)
fakeSimplePing.delegate = pinger
pinger.configureDependencies([fakeSimplePing])
}
it("pings server with data") {
pinger.pingLocation(location)
expect(fakeSimplePing.receivedSendPingWithData).toEventually(beTrue())
}
问题(我相信...)在 pingLocation
行
let simplePings = location.serverIPs.map { ....
您使用与 属性
相同的名字private var simplePings: [SimplePing] = []
所以你可能认为你正在用 let
定义一个新变量,但实际上,你可能只是使用你的 属性 并在途中改变它,所以它变成了 SimplePing
数组,因为它returns来自地图
尝试将您的方法更改为:
func pingLocation(location: Location) -> Signal<Double, NoError> {
let tempSimplePings = location.serverIPs.map { (serverIP: String) -> SimplePing in
let simplePing = SimplePing(hostName: serverIP)
simplePing?.delegate = self
return simplePing
}
configureDependencies(tempSimplePings)
simplePings.forEach { [=12=].start() }
return signal
}