5

iterfaceに次のメソッドシグネチャがあります。

void SetItem(ref AddressItem item);

私はこのようなパラメータ制約を行います:

IAddAddressForm form = Substitute.For<IAddAddressForm>();
AddressItem item = null;
form.SetItem(Arg.Is(item));

しかし、それは参照のために失敗します。refを取り出すと、正常に動作します。しかし、私はここで参照を渡す必要があります。

これを取得する方法はありますか?

補足:私の最終的な目標は、渡された値がnullの場合にSetItemで例外をスローすることです。あなたがそれを手伝うことができれば、あなたは追加のポイントを獲得します!

4

1 に答える 1

10

NSubstituteは、参照パラメーターに一致する引数を直接サポートしていませんが、一般的には問題なく機能します。

質問で述べたように使用する必要があると想定しますが、APIをref回避できれば、refテストも同様に簡単になります(使用するフレームワークに関係なく)。

差し迫った質問に答えるために、2番目のコードサンプルを次のように更新することで参照を渡すことができます。

form.SetItem(ref item);

あなたのサイドノートのために、あなたがあなたの代わりにあまりにも多くの行動を押し込もうとしていないことを確認してください。これを行うときはいつでも、テストしているクラスとその依存関係の間の通信を単純化する必要があることを示しています。(または、偽のオブジェクトに多くのロジックが本当に必要な場合は、生成するのではなく、コードを1つ渡します。多くの場合、より単純な場合があります。)

この呼び出しで例外をスローする方法はいくつかあります。

form.When(x => x.SetItem(ref item)).Do(x => { throw new ArgumentNullException(); });

これは、nullrefで呼び出された場合にのみ例外をスローします。渡された引数に応じてこの動作を選択的に追加することもできますが、これはおそらくあなたが代用者に押し込みすぎている兆候であるため、これに反対することをお勧めします。

form.WhenForAnyArgs(x => x.SetItem(ref item))
    .Do(x => {
        if (x[0] == null)
            throw new ArgumentNullException();
    });

最後に、IAddAddressFormがarg null例外をスローしたときに、テストしているクラスが正しく応答することを確認したいだけの場合は、おそらくこれを実行します。

form
    .WhenForAnyArgs(x => x.SetItem(ref item))
    .Do(x => { throw new ArgumentNullException(); });

そうすれば、引数が何であるかを実際に気にする必要はありません。テストしているコードがこのケースに適切に反応することを確認したいだけです。

お役に立てれば。

サイドノート:

または引数に引数マッチャー(のようなArg.Any<AddressItem>())を使用する場合は、呼び出し自体の外部で定義する必要があります(これは少しエラーが発生しやすい可能性があります:マッチャーを同じ順序で定義する必要があります彼らが電話に出るとき):outref

        IAddAddressForm form = Substitute.For<IAddAddressForm>();
        AddressItem item = Arg.Is<AddressItem>(y => y.Number == 14);
        form
            .When(x => x.SetItem(ref item))
            .Do(x => { throw new ArgumentNullException(); });
        var address = new AddressItem { Number = 14 };
        form.SetItem(ref address);
于 2010-09-25T00:24:56.110 に答える