我需要为每个单元测试都有一个登录用户,这迫使我在我的测试SetUp
中执行异步调用(登录)。
我无法找到使这项工作的方法,我要么得到空指针异常,要么设置无效签名。
public async void SetUp() {}
这使得我的所有测试都失败了,可能是因为我没有登录。
public async Task SetUp() {}
忽略所有测试,因为设置的签名无效。
我不想在每次测试中复制我的X行设置,因为它们完全相同,而且......这就是设置的目的。
我错过了什么?这似乎是一个微不足道的问题。
这是我现在所拥有的,为了展示某些东西
CreateTicketViewModel _viewModel;
[SetUp()]
public async void SetUp() //I have tried using Task instead of void
{
IUserService userService = Dependency.Instance.Resolve<IUserService>();
await userService.LoginAsync(this.UserName, this.Password);
_viewModel = Dependency.Instance.Resolve<CreateTicketViewModel>();
}
[TearDown()]
public void TearDown()
{
_viewModel = null; // I have tried removing this
}
[Test()]
public void Initialization()
{
// If I put what's in SetUp here and add "async" before void,
// it works just fine
Assert.IsNotNull(_viewModel);
Assert.IsNotNull(_viewModel.Ticket);
}
答案 0 :(得分:4)
根据您使用的单元测试框架async
,框架可能无法正确处理设置。
在NUnits案例中,我认为它还不支持异步安装方法。
所以你在安装程序中应该做的就是同步等待登录完成:
userService.LoginAsync(this.UserName, this.Password).Wait()
;
编辑: 看起来它是一个悬而未决的问题https://github.com/nunit/nunit/issues/60
MSTests的情况也是如此。
答案 1 :(得分:2)
难道你不能让你的SetUp方法完全没有异步并写下来吗?
new Task(() => userService.LoginAsync(this.UserName, this.Password)).RunSynchronously()
答案 2 :(得分:2)
不支持异步设置,但支持异步测试方法。您可以使测试方法异步而不是设置方法。
OnError
想法是,我们不是在[TestFixture]
public class AsyncSetupTest
{
private Task<CreateTicketViewModel> viewModelTask;
[SetUp()]
public void SetUp()
{
viewModelTask = Task.Run(async () =>
{
IUserService userService = Dependency.Instance.Resolve<IUserService>();
await userService.LoginAsync(this.UserName, this.Password);
return Dependency.Instance.Resolve<CreateTicketViewModel>();
});
}
[Test()]
public async Task Initialization()
{
CreateTicketViewModel viewModel = await viewModelTask;
Assert.IsNotNull(viewModel);
Assert.IsNotNull(viewModel.Ticket);
}
}
方法中完成所有设置工作,而是创建一个Setup
来表示设置的完成并在Task
方法中等待它。
这样您就不会重复所有设置逻辑。但只是在所有测试方法中从Test
中提取ViewModel。