在c#中设置异步UnitTests

时间:2015-10-20 14:15:19

标签: c# unit-testing asynchronous async-await nunit

我需要为每个单元测试都有一个登录用户,这迫使我在我的测试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);
        }

3 个答案:

答案 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。