Moq lambda表达式出乎意料地表现

时间:2015-07-08 14:11:42

标签: c# unit-testing lambda mocking moq

我使用MOQ进行单元测试,表现出乎意料。我希望IsAuthorizedAsync方法始终返回true,但它返回false。这是代码的简化版本,它将IsAuthorizedAsync方法添加到我的模拟对象中。

    public static IAuthenticationInterface GetAuthentication()
    {
       var mock = new Mock<IAuthenticationInterface>();
       mock.Setup(e => e.IsAuthorizedAsync(It.IsIn<string>(), It.IsAny<MyEvent>())).Returns(System.Threading.Tasks.Task.FromResult(true)).Verifiable();

       // return the mock object
       return mock.Object;
   }

这里的代码类似于使用它的代码:

bool isAuthorized = this.mockObject != null && await this.mockObject.IsAuthorizedAsync("abc123", myEvent).ConfigureAwait(false);

就像我说的那样,当它向我看来它应该总是返回时,它会返回false。有没有办法让我进入lambda表达式代码?或者,有什么方法可以让我查看在调用this.mockObject.IsAuthorizedAsync时使用的实际lambda表达式是什么?我怀疑它不是我认为的。

-Eric

1 个答案:

答案 0 :(得分:0)

根据@ tzachs&#39;注释,请注意It.IsIn匹配器会获取匹配值列表(实例中的字符串)。空It.IsIn()params的{​​{1}}将永远不会匹配任何内容,因为它是使用IEnumerable实现的:

.Contains

因此无法返回所需的结果。你想要改变它,例如

public static TValue IsIn<TValue>(IEnumerable<TValue> items)
{
   return Match.Create<TValue>((Predicate<TValue>) 
     (value => Enumerable.Contains<TValue>(items, value)), 
     (Expression<Func<TValue>>) (() => It.IsIn<TValue>(items)));
}

另外,请注意,在使用Async方法时,Moq(以及NUnit和XUnit等测试框架)支持It.IsAny<string>() // ... Any string at all It.Is<string>(s => s == "Foo") // ... Match via a Predicate It.IsIn<string>("Foo", "Bar", "Baz") // ... Match via a List 语义。因此,而不是黑客攻击&#39;一个Async,您可以做的是:

Task.FromResult

(是的,我知道我只是在这里测试模拟:)