9

このコード:

hub.MockedUserRepository.Setup(r => r.Update(It.IsAny<ControllUser>()))
                        .Callback((ControllUser usr) => Console.WriteLine("NULL = " + (usr.Zombies[0].ConnectionId == null)))
                        .Verifiable();

印刷します

NULL = 真

だから私はこのマッチングを使用するとそれをキャッチすると考えています:

var zombieDisconnectParameterMatcher = It.Is<ControllUser>(x => x.Zombies[0].ConnectionId == null);
hub.MockedUserRepository.Setup(r => r.Update(zombieDisconnectParameterMatcher))
                        .Callback((ControllUser usr) => Console.WriteLine("NULL = " + (usr.Zombies[0].ConnectionId == null)))
                        .Verifiable();

しかし、そうではありません。

なんで?

4

2 に答える 2

11

のソース コードをIt見ると、式ツリーに関係しています。私はその質問が好きです。それらは非常に不可解です。次のメソッド定義を見てみましょう。

public static TValue It.Is<TValue>(Expression<Func<TValue, bool>> match)
{
        return Match<TValue>.Create(
                value => match.Compile().Invoke(value),
                () => It.Is<TValue>(match));
}

public static T Match.Create<T>(Predicate<T> condition, Expression<Func<T>> renderExpression)
{
        // ...
        return default(T);
}

次の行を実行するとします。

var zombieDisconnectParameterMatcher = It.Is<ControllUser>(x => x.Zombies[0].ConnectionId == null);

次にIt.Is<ControllUser>()、 というメソッドを呼び出そうとします。このメソッドMatch.Create<ControllUser>()は、デフォルトの を返しますControllUserControllUserはクラスであると想定しているため、zombieDisconnectParameterMatcherになりますnull。これはデバッガーで確認できるはずです。したがって、実際に呼び出しているのは次のとおりです。

hub.MockedUserRepository.Setup(r => r.Update(null))
    .Callback((ControllUser usr) => Console.WriteLine("NULL = " + (usr.Zombies[0].ConnectionId == null)))
    .Verifiable();

Updatenull 以外でメソッドを実行する場合ControllUser(たとえば、テストされているメソッドから)、コールバックはトリガーされません。null ではないため、条件に一致しません。検証も失敗することがわかります。

この問題を解決するには、zombieDisconnectParameterMatcher変数をインライン化するか、式型の変数 (例: Expression<Func<...>>) にします。後者は、コードが実行されないことを確認しますが、モック フレームワークが推論できる式として扱われます (' ?'Updateで呼び出されZombies[0].ConnectionId == nullます)。

于 2013-03-12T22:21:18.743 に答える
1

ControllUserインスタンスがどのようにインスタンス化されるかによって異なります。モック内で参照するインスタンスが、テスト対象のコードで参照される実際のインスタンスでない場合、Setupは失敗します。ControllUserテスト対象のコードで参照されるのインスタンスが、テスト コード内のオブジェクトと同じであることを確認する必要があります。It.IsAny<ControllUser>()そうでない場合は、最初の例が示すように、コールバックを使用してテストする必要があります。テストしているコードをもっと見ずして、確実に言うのは難しいです。

于 2013-03-12T22:10:19.877 に答える