ios - Swift:基类数组不调用子类函数实现

标签 ios swift unit-testing mocking

我正在尝试将一个假实例注入(inject)到一个类的单元测试中,该类依赖于 NSObject 子类 SimplePing。我的类有一个属性 var simplePings: [SimplePing] 在我的单元测试中我将其设置为 FakeSimplePing 的数组。但是,当类进入数组并调用 simplePing.start() 时,它会调用 SimplePing.start 实现而不是 FakeSimplePing 的实现,即使在调试时我看到实例类型是 FakeSimplePing。

当属性只是单个 SimplePing 时,单元测试使用 FakeSimplePing.start 并且测试通过。这与 Swift 和父类(super class)数组有关吗?

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
    }
}

失败的测试:

            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 { .... 

您使用与您的属性(property)相同的名称

private var simplePings: [SimplePing] = []

所以您可能认为您正在使用 let 定义一个新变量,但实际上,您可能只是使用您的属性并在途中更改它,因此它更改为 SimplePing 数组,因为它从 map 返回

尝试将您的方法更改为:

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
   }

关于ios - Swift:基类数组不调用子类函数实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35321170/

相关文章:

python - 当我在 Django 中创建一个测试方法时, 'self' 到底指的是什么?

python - mock.patch 的正确路径

ios - 当我从基类以编程方式替换 UIViewController 的根 UIView 时,我的 Outlets 为零

ios - 透明导航栏下的UITableView

ios - 从 tableView 中选定的行打开 Map AnnotationView

ios - Swift 项目中 Objective-C 的条件编译

.net - RhinoMocks 是否死了?

ios - 将 pdf 文档保存到 iOS 文件应用程序时如何指定文件名?

JavaScriptCore - 在 iOS 中访问 DOMParser

ios - glPushMatrix() 和 glPopMatrix() 抛出 GL_INVALID_OPERATION