2017-06-08 13 views
0

入力引数としてプロトコルを受け取る関数の単体テストを書いています。
私がテストしているこの関数は、内部でそのプロトコルのいくつかのメソッドを呼び出します。 私はこのプロトコルとその方法を模擬したい。 id<MyProtocol> myProtocol = OCMProtocolMock(@protocol(MyProtocol));NSInvocationから 'function'型の引数を取り出す方法

は、今私はOCMStubを使用しています機能をモックする:
は、私は次のように書いたOCMock使用してプロトコルを模擬するために。 興味深いのは、関数が値を返すのではなく、入力引数としてコールバックを取得して呼び出すことです。 - (void)myFunction:(void (^ _Nonnull)(NSDictionary<NSString *, NSString *> * _Nonnull))completion;

私はこの機能をモックするには、次のコードを書いています:
私は次のようなエラーになっていますが OCMStub([myProtocol myFunction:[OCMArg any]])._andDo(^(NSInvocation *invocation){ void (^ _Nonnull)(NSDictionary<NSString *, NSString *> * _Nonnull) completion; [invocation getArgument:&completion atIndex:0]; // Here I will invoke the completion callback with some dictionary and invoke the invocation });

:「Expected identifer or '('」を は、ここでその署名です。エラーは、completionという変数を定義する行を指しています。

シグニチャーvoid (^ _Nonnull)(NSDictionary<NSString *, NSString *> * _Nonnull)の関数変数はどのように定義できますか?

答えて

0

は、実際に私は、次の手順を実行して、最初の引数を抽出することができました:
OCMStub([myProtocol myFunction:[OCMArg any]])._andDo(^(NSInvocation *invocation){ void (^ completion)(NSDictionary<NSString *, NSString *> * _Nonnull); [invocation getArgument:&completion atIndex:2]; // Do other stuff });

私は間違って「ブロック」型の変数を宣言しました。
また、最初の引数にはindex = 2でアクセスする必要があります。

1

これは機能ではありません。ブロックです!

いずれの関数およびブロックも宣言でvoid *として扱うことができます。後に適切なタイプにキャストする必要があります。

しかし、これはおそらく最も簡単な方法です。呼び出しからブロックvoid*として抽出し、ブロックにキャストして呼び出します。

+0

ありがとうございます!ブロックにキャストする方法の例を追加することもできますか? –

+1

「ブロック」という名前になっていることに感謝します!私は 'ブロック'タイプの変数を作成する方法を学び、問題を解決しました。 'void *'変数を宣言してブロックにキャストする必要はありません。ブロックタイプの変数のアドレスは '[NSInvocation getArgument]'に直接渡すことができるので –

関連する問題