gpt4 book ai didi

c# - 测试错误 : The 'async' operator lacks await operator

转载 作者:行者123 更新时间:2023-11-30 20:27:55 27 4
gpt4 key购买 nike

我有一个单元测试来检查 null 参数。测试方法是这样的:

[TestMethod]
public async Task Test_NullParam()
{
Mock<IAuth> mockAuth = new Mock<IAuth>();
Task<AuthenticationResult> mockResult = null;

await Assert.ThrowsExceptionAsync<ArgumentNullException>(async () =>
{
mockAuth
.Setup(x => x.Authenticate(null, param2, param3, param4))
.Returns(mockResult);
});
}

(async () 下显示错误。

错误是:

The async lacks await operator

mockResult 显示:

Result is always null

** 已编辑 **

类代码如下:

  public async Task<AuthenticationResult> Authenticate(string param1, string param2, string param3, string param4)
{
try
{
var authContext = new AuthenticationContext(param1);
if (authContext.TokenCache.ReadItems().Any()) authContext = new AuthenticationContext(authContext.TokenCache.ReadItems().First().Authority);
var authResult = await
authContext.AcquireTokenAsync(param2, param3, new Uri(param4), new PlatformParameters(PromptBehavior.Auto, false));
return authResult;
}
catch (Exception)
{
return null;
}
}

最佳答案

您收到错误是因为您没有执行 await您传递给 ThrowsExceptionAsync 的 lambda 中的语句.

更重要的是,您似乎是在 lambda 中执行模拟设置,而不是实际执行您正在测试的方法。您应该将模拟移到 lambda 之外,并像这样在 lambda 中执行您正在测试的方法:

[TestMethod]
public async Task Test_NullParam()
{
// create all of your mocks that are required to run this test
Mock<IAuth> mockAuth = new Mock<IAuth>();
Task<AuthenticationResult> mockResult = null;
mockAuth
.Setup(x => x.Authenticate(null, param2, param3, param4))
.Returns(mockResult);

// you actually need to create the concrete type you want to test
// you shouldn't make a unit test that just uses mocks!

// construct the concrete type and pass in any mocks that the
// object requires
var objectToTest = new MyRealObject(mockAuth.Object);

await Assert.ThrowsExceptionAsync<ArgumentNullException>(async () =>
{
// actually execute the real method here, the assertion
// is expecting this method to throw an exception, and will
// only pass if an exception is thrown
await objectToTest.MyMethodAsync();
});
}

请注意,如果您正在测试的方法不是异步的,您应该将单元测试更改为非异步的,并使用 Assert.ThrowsException相反。

编辑:

回应您关于模拟 Task 的评论, 如果你想模拟 Task返回 null AuthenticationResult ,您应该执行以下操作:

// declare the result
AuthenticationResult mockResult = null;

// set up the authenticate method to return the task
mockAuth
.Setup(x => x.Authenticate(null, param2, param3, param4))
.Returns(Task.FromResult(mockResult));

这里重要的部分是Task.FromResult .这会给你一个实际的 Task ,这将返回 null等待时,而不是 Task正在null本身。

如果你想使用 AuthenticationResult那不是空的,你会遇到问题,由于 AuthenticationResult没有公共(public)构造函数的类,除了实际运行一个真正的 Authenticate 请求之外,没有办法获得一个。开箱即用,AuthenticationResult不可模拟,这就是为什么@Nkosi 提供了一篇关于 using wrapper classes to make it mockable 的文章的链接.

编辑2

链接的博文似乎不完整,因为它没有包含所有需要的包装器类型,所以我决定自己制作它们,这样这个答案就可以完整了。

由于 StackOverflow 答案的字符限制限制,我不得不将文件放在 Github 上:https://github.com/DoctaJonez/DoctorJones.IdentityModel.Clients.ActiveDirectory/tree/master

添加这些类和接口(interface)后,您将能够执行以下操作:

// you can now mock authentication results, and set them up to 
// emulate whatever conditions you like
var mockResult = new Mock<IAuthenticationResultWrapper>();

// you'll need to use the IAuthenticationContextWrapper, so all the
// method signatures know about our new IAuthenticationResultWrapper
var mockAuth = new Mock<IAuthenticationContextWrapper>();

// here's how we mock the IAuthenticationContextWrapper to return our
// mocked IAuthenticationResultWrapper
mockAuth.Setup(x => x.Authenticate(null, param2, param3, param4))
.Returns(Task.FromResult(mockResult.Object));

关于c# - 测试错误 : The 'async' operator lacks await operator,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48165296/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com