如何在WPF中使用异步初始化对ViewModel进行单元测试 [英] How to Unit test ViewModel with async initialization in WPF

查看:260
本文介绍了如何在WPF中使用异步初始化对ViewModel进行单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个示例WPF MVVM项目,现在我想对其进行单元测试. 视图模型在构造函数中异步加载数据:

I have created a sample WPF MVVM project which I now want to Unit test. The viewmodels load the data asynchronously in the constructor:

public class CustomerOverviewViewModel
{
   public CustomerOverviewViewModel()
   {
       var t = LoadFullCustomerListAsync();
   }
   public async Task LoadFullCustomerListAsync()
   {
      List<BL_acc> customers = await Task.Run(() => // Query from db);
   }
}

在WPF中,这就像一个吊饰. 当我想为此视图模型创建单元测试时,我通过调用其默认构造函数来创建对象:

In WPF, this works like a charm. When I want to create a unit test for this viewmodel, I create the object by calling its default constructor:

  [TestMethod]
  public void Test()
  {
      customerOverviewViewModel = new CustomerOverviewViewModel();
      // Do the test
  }

但是,单元测试无法知道异步方法何时完成. 可以使用构造函数初始化来解决此问题,还是应该使用其他模式?

However, the unit test has no way of knowing when the async method is finished. Can this be fixed using constructor initialization or should I use a different pattern?

修改

单元测试不需要异步加载的信息,它们只需要类的实例即可测试方法. 仅仅为我的单元测试使用另一种初始化方法似乎是很多额外的工作.

The unit tests don't need the async loaded information, they just need an instance of the class to test the methods. It just seems like a lot of extra work to use another initialization method just for my unit tests.

所有单元测试均成功,但有时会引发错误,即多个线程尝试访问同一上下文(当数据未异步加载时消失):

All the unit tests succeed but they sometimes throw an error that multiple threads try to access the same context (which disappears when the data is not loaded async):

在创建模型时不能使用上下文.如果在OnModelCreating方法内部使用上下文,或者多个线程同时访问同一上下文实例,则可能引发此异常.请注意,不能保证DbContext和相关类的实例成员是线程安全的.

推荐答案

在WPF中,这就像一个吊饰.

In WPF, this works like a charm.

排序.如当前所写,初始化"任务只是被忽略.因此,没有错误处理,也没有向UI指示初始化正在进行或已完成(即,它没有办法知道何时显示微调框).

Sort of. As currently written, the "initialization" task is just ignored. So, there's no error handling, and there's no indication to the UI that the initialization is in progress or completed (i.e., there's no way for it to know when to show a spinner).

换句话说,显示此信息(状态以及结果数据)将不仅对单元测试代码有用,还对更多有用.我有一个简单的数据可绑定的任务包装器,我之前写过在这种情况下提供帮助.

In other words, surfacing this information (state as well as the resulting data) would be useful to more than just the unit test code. I have a straightforward data-bindable task wrapper that I wrote a while ago to help in situations like this.

如果异步方法返回Task,则没有其他方法可以检测到异步方法的完成.您必须以某种方式公开Task.我认为公开它的最佳方法是类似于我编写的类型,以便UI也可以使用它.

There isn't an alternative way to detect the completion of asynchronous methods if they return a Task; you'd have to expose the Task somehow. I think the best way of exposing it is something like the type I wrote, so that the UI can make use of it as well.

这篇关于如何在WPF中使用异步初始化对ViewModel进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆