Moq lambda表达式行为异常
本文关键字:异常 表达式 lambda Moq | 更新日期: 2023-09-27 18:01:51
我有一个使用最小起订量的单元测试,它的行为出乎意料。我期望IsAuthorizedAsync方法总是返回真,但它返回假。下面是代码的简化版本,它将IsAuthorizedAsync方法添加到我的Mock对象。
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);
就像我说的,当它看起来应该总是返回真时,它返回假。是否有任何方法让我进入lambda表达式代码?或者,是否有任何方法让我查看实际的lambda表达式,正在使用当我调用this.mockObject.IsAuthorizedAsync?我怀疑它不是我想的那样。
eric
根据@tzachs的评论,请注意It.IsIn
匹配器接受匹配值的列表(在您的实例中是字符串)。It.IsIn()
与空params
或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)));
}
因此无法返回期望的结果。你可能想要改变这个,例如
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
另外,请注意,当使用异步方法时,Moq(以及像NUnit和XUnit这样的测试框架)支持Async
语义。所以,你可以做的不是"黑"一个Task.FromResult
,而是:
[Test]
public async void MyTest() // ... The UT can be made async
{
var mock = new Mock<IAuthenticationInterface>();
mock.Setup(e => e.IsAuthorizedAsync(It.IsIn<string>("Foo"), It.IsAny<MyEvent>()))
.ReturnsAsync(true) // ... Async
.Verifiable();
// async calls can be awaited
Assert.True(await mock.Object.IsAuthorizedAsync("Foo", null));
}
(是的,我知道我只是在这里测试Mock:)