这段代码:

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

会列印



所以我想使用此匹配将捕获它:
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();

但事实并非如此。

为什么?

最佳答案

通过查看source code of 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>()的方法,该方法返回ControllUser的默认值。我假设ControllUser是一个类,因此zombieDisconnectParameterMatcher将是null。您应该能够在调试器中看到这一点。因此,您实际上要拨打的电话是:
hub.MockedUserRepository.Setup(r => r.Update(null))
    .Callback((ControllUser usr) => Console.WriteLine("NULL = " + (usr.Zombies[0].ConnectionId == null)))
    .Verifiable();

当使用非空Update(例如,正在测试的方法)执行ControllUser方法时,将不会触发回调。它根本不符合条件,因为它不为null。您也会看到验证失败。

要解决此问题,请内联zombieDisconnectParameterMatcher变量,或使其成为表达式类型的变量(例如Expression<Func<...>>)。后者将确保不执行代码,而是将其视为模拟框架可以推理的表达式(“是否用Update调用Zombies[0].ConnectionId == null?”)。

关于c# - Moq It.Is <>不匹配,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15372226/

10-11 17:27