2
void ABC()
{
    var foo = Substitute.For<IFoo>();
    foo.When(x => x.Bar()).Do(x => counter++);
    <use Bar()>.... 1
    foo.When(x => x.Bar()).Do(x => counter--);
    <use Bar()>.... 2
}

上記のコードスニペットでは、(1)と(2)の両方がcounter ++動作を表示しており、When...Do動作がオーバーライドされていないことを示しています。さまざまなコールバックをフックアップするテストシナリオを生成するには、この動作が必要です。

これをどのように達成する必要がありますか?

4

1 に答える 1

5

コールバックはDo置き換えられませんが、両方が実行されます。例 (NSub 1.4.3.0 を使用):

var counter = 0;
var sub = Substitute.For<IFoo>();
sub.When(x => x.Bar()).Do(x => counter++);
sub.Bar();
Console.WriteLine(counter);  // prints 1
sub.When(x => x.Bar()).Do(x => counter--);
sub.Bar();
Console.WriteLine(counter);  // prints 1, as counter gets inc'd to 2, then dec'd to 1

その使用はカプセル化の失敗の症状になる可能性があるため、控えめに使用することをお勧めします。置換されたオブジェクトに動作を強制することは、テストしているクラスが、置換しているインターフェイスではなく、依存クラスの動作に深く結合していることを示している可能性があります。

その免責事項を使用して、コールバックを交換できる 1 つの方法は、ヘルパー クラスを使用して特定のコールバックを提供することです。

[Test]
public void Example() {
    var counter = 0;
    var helper = new CallbackHelper();
    helper.Callback = x => counter++;
    var sub = Substitute.For<IFoo>();

    sub.When(x => x.Bar()).Do(x => helper.Callback(x));
    sub.Bar();
    Console.WriteLine(counter);

    helper.Callback = x => counter--;
    sub.Bar();
    Console.WriteLine(counter);

    helper.Callback = x => { counter = (counter+1) * 10; };
    sub.Bar();
    Console.WriteLine(counter);
}

public class CallbackHelper {
    public Action<CallInfo> Callback;
}

/* Prints:
    1
    0
    10
*/

達成しようとしている振る舞いの交換の具体的な例を投稿すると、これを完全に使用しないようにインターフェイスの変更を思い付くことができるかもしれません。

お役に立てれば。:)

于 2013-01-13T01:57:14.570 に答える