2016-05-24 14 views
3

とプロトコルのモックだから私はジェネリックのFunc

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シグネチャでUをTに置き換えた場合、sendEvent =イベント行に、タイプTのものを_ _タイプのものに割り当てることができないというエラーが表示されます。私がSwiftジェネリックについて知っていることから、なぜこれらのエラーが出ているのか理解しています。私が知りたいことは、私がやろうとしていることをやり遂げることができれば、基本的にプロトコルを汎用関数で模倣し、値を取得して検証できるかどうかです。あなたはそれを実装する場合、関数のシグネチャと一致する必要が

答えて

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]) 
+0

恐ろしいのは、これは今、私はそれを見ていることは明らかと思われます。あなたが間違ったMyMessageを送信すると、キャストが少しハッキリのように見えますが、キャストが失敗する可能性がありますが、単体テストです。ありがとう!! –

+0

'U'と' T'の両方が 'MyMessage'に準拠するので、常にキャストが成功します。コンパイラは 'as!'が決して 'nil'を返さないという苦情を投げます。 –

+0

これは本当ですが、ユニットテストの外でこのパターンを使用しようとすると予期しない動作やクラッシュを引き起こす可能性があります。私がSenderプロトコルを実装している実際のクラスは、MyMessageプロトコルのみを使用し、キャストを行わないので安全です。答えにもう一度感謝、あなたは私に多くの時間を節約しました。 –

関連する問題