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

查看传递给什么参数的一种方法PeriodPassed是使用 JustMock 的DebugView

放置DebugView.IsTraceEnabled = true;在测试的开头并添加DebugView.CurrentState到手表中。接近尾声时,你会看到一些类似的东西: Invocations: (ByRef ...).PeriodPassed("period value will go here") called 1 time; (signature: ...)

周期值将显示在调用列表中。

另一种方法是将匹配器提取到单独的 lambda 并使用断点: 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

正如 Stefan Dragnev 所写的那样。我使用了他的想法,然后添加了逻辑来验证输入。如果不是称为 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

之前添加额外的安排也对我有用,但它非常hacky:

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 回答