使用通用函数模拟协议

时间:2016-05-24 01:52:32

标签: swift unit-testing generics

所以我有以下Swift协议......

protocol MyMessage {
    func encodeMessage() -> [String:AnyObject]
}

protocol Sender {
    func send<T:MyMessage>(id:Int,event:T)
}

我在我编写的一些代码中使用它们就好了。现在我想编写一些单元测试并模拟Sender协议。基本上我想捕获id和事件,所以我可以在单元测试中检查它们,我将Sender传递给被测试的类。所以我开始编写模拟器,在我意识到它不起作用之前我已经做到了这一点。

class MockSender<U : MyMessage> : Sender {
    var sentEvent : U?
    var sentId : Int?

    func send<T:U>(id:Int,event:T) {
        sendId = id
        // save message so I can verify it
        sentEvent = event
    }
}

问题在于我无法弄清楚如何将U的类型与T的类型联系起来。编译器说U不是协议,这是有道理的。如果我在MockSender签名中用T替换U,则sendEvent =事件行会被标记为错误,我无法将类型为T的东西分配给类型_?的某些东西。根据我对Swift泛型的了解,我理解为什么会出现这些错误。我想知道的是,如果有一些我可以做我想做的事情,基本上用泛型函数模拟协议并捕获值,以便我可以验证它。

1 个答案:

答案 0 :(得分:0)

实现时必须匹配函数的签名:

class MockSender<U: MyMessage> : Sender {
    var sentId: Int?
    var sentEvent: U?

    func send<T : MyMessage>(id: Int, event: T) {
        sentId = id
        sentEvent = event as? U
    }
}

用法:

struct Message: MyMessage {
    func encodeMessage() -> [String : AnyObject] {
        return ["firstName": "John", "lastName": "Smith"]
    }
}

let msg = Message()

let mock = MockSender<Message>()
mock.send(1, event: msg)

print(mock.sentEvent?.encodeMessage()) // Optional(["firstName": John, "lastName": Smith])