[英]Swift: Array of base class does not call subclass function implementation
I'm trying to inject a fake instance into a unit test for a class depending on SimplePing, a NSObject subclass. 我正在尝试根据NSObject子类SimplePing将虚假实例注入到类的单元测试中。 My class has a property
var simplePings: [SimplePing]
which in my unit test I set as an array of FakeSimplePing. 我的课有一个属性
var simplePings: [SimplePing]
,在我的单元测试中,我将其设置为FakeSimplePing数组。 However, when the class goes in the array and calls simplePing.start()
, it calls the SimplePing.start implementation instead of FakeSimplePing's, even though when I debug I see that the instance type is FakeSimplePing. 但是,当类进入数组并调用
simplePing.start()
,它会调用SimplePing.start实现而不是FakeSimplePing的实现,即使在调试时我看到实例类型是FakeSimplePing。
When the property is just a single SimplePing, the unit test uses the FakeSimplePing.start and the test passes. 当属性只是单个SimplePing时,单元测试将使用FakeSimplePing.start并通过测试。 Does this have something to do with Swift and arrays of superclasses?
这与Swift和超类数组有关吗?
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 { $0.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
}
}
And the failing test: 和失败的测试:
beforeEach {
fakeSimplePing = FakeSimplePing(hostName: serverIP)
fakeSimplePing.delegate = pinger
pinger.configureDependencies([fakeSimplePing])
}
it("pings server with data") {
pinger.pingLocation(location)
expect(fakeSimplePing.receivedSendPingWithData).toEventually(beTrue())
}
The problem (I believe...) is in the naming in pingLocation
问题(我相信...)是在
pingLocation
中命名
in the line 在行中
let simplePings = location.serverIPs.map { ....
you use the same name as of your property 您使用与财产相同的名称
private var simplePings: [SimplePing] = []
so you may think you're defining a new variable with the let
, but actually, you may just use your property and change it on the way, so it got changed to SimplePing
array, as it returns from the map 因此您可能会认为您正在使用
let
定义一个新变量,但实际上,您可能只是使用您的属性并在途中对其进行了更改,因此它从地图返回时更改为SimplePing
数组。
try to change your method into: 尝试将您的方法更改为:
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 { $0.start() }
return signal
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.