2

私は JustMock フレームワークを使用しており、次のアサーションがあります。

Mock.Assert(() => activityListenerMock.PeriodPassed(
  Arg.Matches<Period>(e => e.Length == expectedLength)));

不可解なメッセージで失敗します:

Occurrence expectation failed. Expected at least 1 call. Calls so far: 0

より良いメッセージを得るにはどうすればよいですか。どのような値で呼ばれていたのか知​​りたいです。

メソッドは実際に呼び出されますが、アサーションを次のように変更するとパスするため、間違った引数で呼び出されます。

Mock.Assert(() => activityListenerMock.PeriodPassed(
  Arg.IsAny<Period>()));
4

4 に答える 4

6

渡された引数を確認する 1 つの方法は、JustMock のDebugViewPeriodPassedを使用することです。

テストの最初に配置し、時計DebugView.IsTraceEnabled = true;に追加します。DebugView.CurrentState終わりに向かって、あなたはこれの曲に何かを見るでしょう: Invocations: (ByRef ...).PeriodPassed("period value will go here") called 1 time; (signature: ...)

期間の値は呼び出しリストに表示されます。

これを行う別の方法は、マッチャーを別のラムダに抽出し、ブレークポイントを使用することです。 Predicate<Period> matcher = e => e.Length == expectedLength; Mock.Assert(() => activityListenerMock.PeriodPassed( Arg.Matches<Period>(e => matcher(e))));

eこれで、述語内にブレークポイントを配置して、引数の値を確認できます。これは、述語が式ではなく実際の関数であるため機能するため、デバッグできるようになりました。

于 2014-10-03T10:07:14.357 に答える
3

ステファン・ドラグネフが書いたものに。私は彼のアイデアを使用し、入力を検証するロジックを追加しました。Assert.Fail() と呼ばれる期待値でない場合。より良い方法があるかどうかはわかりませんが、これは機能します:

Mock.Arrange(() => _uowMock.Class.Add(
    Arg.Matches<ModelClass>(x => (CheckArgs(x, updated)))))
    .DoNothing().Occurs(3);

....

protected static bool CheckArgs(ModelClass x, int y)
{
    if (x.val != y)
    {
        Assert.Fail("Houston we have a problem");
    }

    return true;
}
于 2015-05-04T18:09:48.740 に答える
0

前に追加のアレンジを追加することもできましたが、非常にハッキーです:

Mock.Arrange(() => activityListenerMock.PeriodPassed(Arg.IsAny<Period>())).
  DoInstead((Period p) => Console.WriteLine("Actual " + p.Length+" expected "+expectedLength));
于 2014-10-04T08:24:48.947 に答える
0

今日、これと同じジレンマに陥り、Krzysztof のアイデアをいくつか拡張して拡張し始めました。ラフですが機能的です。

public static class JustMockExtensions {
        public static FuncExpectation<T> PrintParams<T, T1>(this FuncExpectation<T> mock) {
            return mock.DoInstead<T1, T>((arg1, arg2) => {
                string message = string.Empty;
                message += Process(arg1);
                message += Process(arg2);
                Console.WriteLine(message);
            });
        }

        private static string Process<T>(T obj) {
            if (typeof(T).IsEnum) {
                return Enum.GetName(typeof(T), obj);
            }
            return obj.ToString();
        }
    }

これまでのところ、この方法を使用すると、通常の流れでパイプすることができます。

Mock.Arrange(() => foo.bar(Arg.IsAny<Widget>(), Arg.IsAny<WidgetTypeEnum>()))
                .PrintParams<Widget, WidgetTypeEnum>()
                .MustBeCalled();
于 2015-09-30T13:24:52.227 に答える