[英]Moq lambda expression behaving unexpectedly
I have a unit test using MOQ that's behaving unexpectedly. 我有一个使用最小起订量的单元测试,表现出乎意料。 I'm expecting the IsAuthorizedAsync method to always return true, but it's returning false.
我期望IsAuthorizedAsync方法始终返回true,但是返回false。 Here's a simplified version of the code that's adding the IsAuthorizedAsync method to my Mock Object.
这是将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;
}
Here's code similar to the code that's using it: 这是与使用它的代码相似的代码:
bool isAuthorized = this.mockObject != null && await this.mockObject.IsAuthorizedAsync("abc123", myEvent).ConfigureAwait(false);
Like I said, it's returning false when it looks to me like it should always return true. 就像我说的那样,当它看起来应该总是返回true时,它返回false。 Is there any way for me to step into the lambda expression code?
我有什么办法进入lambda表达式代码? Alternatively, is there any way for me to view what the actual lambda expression that's being used when I call this.mockObject.IsAuthorizedAsync?
另外,当我调用this.mockObject.IsAuthorizedAsync时,是否有任何方法可以查看正在使用的实际lambda表达式? I suspect it's not what I think it is.
我怀疑这不是我想的。
-Eric -Eric
As per @tzachs' comment, note that the It.IsIn
matcher takes a list of matching values (strings in your instance). 根据@tzachs的评论,请注意
It.IsIn
匹配器采用匹配值(实例中的字符串)的列表。 It.IsIn()
with an empty params
or IEnumerable
will never match anything, as it is implemented with .Contains
: 带有空
params
或IEnumerable
It.IsIn()
将永远不会匹配任何内容,因为它是通过.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)));
}
hence the failure to return the desired result. 因此无法返回预期的结果。 You'll want to either change this eg
您可能想要更改此,例如
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
Also, note that when working with Async methods, that Moq (and Test Frameworks like NUnit and XUnit) have support for Async
semantics. 另外,请注意,使用Async方法时,Moq(以及诸如NUnit和XUnit的测试框架)都支持
Async
语义。 So instead of 'hacking' a Task.FromResult
, what you can do instead is: 因此,代替“黑客”
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));
}
(and yes, I know I'm just testing the Mock here :) (是的,我知道我只是在这里测试Mock :)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.