C# MVVM,使用线程获取数据+;测验

C# MVVM,使用线程获取数据+;测验,c#,wpf,mvvm,tdd,C#,Wpf,Mvvm,Tdd,我在考虑如何测试以下场景:我有一个负责获取数据的viewmodel,它还包含一些其他信息,比如负责某些元素可见性的参数以及视图可以绑定到的其他信息。让我们假设它看起来像这样(简化的场景): 我应该如何处理这个问题?这里让我困惑的是线程的使用。谢谢你的提示。这是一个有趣的标题,你有。。。这似乎与你的问题无关。它说的是MVVM,通过线程+测试来获取数据,但您的问题是测试名为的UI属性是否应在加载时保存LoadingIndicator VisibleWhenLoadingMessages。所以这不是关

我在考虑如何测试以下场景:我有一个负责获取数据的viewmodel,它还包含一些其他信息,比如负责某些元素可见性的参数以及视图可以绑定到的其他信息。让我们假设它看起来像这样(简化的场景):


我应该如何处理这个问题?这里让我困惑的是线程的使用。谢谢你的提示。

这是一个有趣的标题,你有。。。这似乎与你的问题无关。它说的是MVVM,通过线程+测试来获取数据,但您的问题是测试名为
的UI属性是否应在加载时保存LoadingIndicator VisibleWhenLoadingMessages
。所以这不是关于用线程获取数据

我之所以这么说是因为测试数据访问和测试UI是两件完全不同的事情。如果您只是想测试UI,那么您应该看看MSDN上提供了什么

但是,如果您只想测试是否设置了特定属性,而不考虑其在UI中的效果,那么您可以对视图模型使用普通测试。制作一个可测试的应用程序的秘密是连接所有相关的功能

我的意思是,您可以有一个
ThreadManager
类来为您处理所有多线程。然后需要一个
IThreadManager
接口和一个
MockThreadManager
接口,该接口实现
IThreadManager
接口,但实际上在主UI线程上执行代码,而不是
ThreadManager
类提供的正常功能。话虽如此,在测试时,在不同线程中运行代码不是问题,只要结果正确合并

更重要的是,
DataProvider
类及其
IDataProvider
接口和
MockDataProvider
“假”数据提供程序,这样您就可以在不接触数据库中实际数据的情况下测试视图模型

public class ViewModel : INotifyPropertyChanged
{
    public ObservableCollection<MessageViewModel> Objects { get; set; }
    private List<MessageDto> _someData; 

    private bool _loadingIndicatorVisible;
    public bool LoadingIndicatorVisible 
    { 
       get { return _loadingIndicatorVisible; } 
       set { _loadingIndicatorVisible = value; OnPropertyChanged(); 
    }

    private bool _isLoading;

    public void StartGettingData()
    {
        if (_isLoading)
            return;

        _isLoading = true;
        LoadingIndicatorVisible = true;

        var taskForGettingData = Task.Factory.StartNew(() => _someData =  WebService.GetMessages());
        taskForGettingData.ContinueWith(task => EndGettingData(), TaskContinuationOptions.NotOnFaulted);
    }

    public void EndGettingData()
    {
        _isLoading = false;
        LoadingIndicatorVisible = false;

        //convert _someData to ObservableCollection<MessageViewModel> - implementation irrelevant
    }
}
void ShouldHaveLoadingIndicatorVisibleWhenLoadingMessages() { /* ... */ }