MVVM light Dispatcher单元测试 [英] MVVM light Dispatcher unit tests

查看:94
本文介绍了MVVM light Dispatcher单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我具有以下功能

 public void Reset()
 {
     DisableModule();
     DispatcherHelper.UIDispatcher.Invoke(() =>
     {
           PixelPointInfoCollection.Clear();
           PixelPointInfoCollection.Add(new PointViewModel());
     });
     _cachedPoints.Clear();
 }

在运行单元测试时,以下代码卡在Invoke()方法中.

The following code gets stuck in the Invoke() method, when running a unit test.

我看到了一些有关在调度程序上创建自定义接口并在单元测试中模拟调度程序的文章. 例如 http://blog.zuehlke.com/en/mvvm-and-单元测试/

I saw some articles about creating a custom interface on dispatcher and mocking the dispatcher in unit tests. for example http://blog.zuehlke.com/en/mvvm-and-unit-testing/

还有别的办法吗?我有一个庞大的代码库..我真的需要现在更改所有内容吗?

Is there no other way? I have a huge code base.. do I really need to change everything now?

更新18.8.2016 目前,这是我所做的并且正在运行

Update 18.8.2016 For now here is what I did and it is working

public static class AppServices
{

    public static IDispatcher Dispatcher { get; set; } 
    public static void Init(IDispatcher dispatcher)
    {
        Dispatcher = dispatcher;
    }
}

//this inteface is in order to overrcome MVVM light Dispatcher so we can mock it for unit tests
public interface IDispatcher
{
    void Invoke(Action action);
    void Invoke(Action action, DispatcherPriority priority);
    DispatcherOperation BeginInvoke(Action action);
}

public class DispatcherWrapper :IDispatcher
{
    public DispatcherWrapper()
    {
        DispatcherHelper.Initialize();
    }
    public void Invoke(Action action)
    {
        DispatcherHelper.UIDispatcher.Invoke(action);
    }

    public void Invoke(Action action, DispatcherPriority priority)
    {
        DispatcherHelper.UIDispatcher.Invoke(action, priority);
    }

    public DispatcherOperation BeginInvoke(Action action)
    {
       return DispatcherHelper.UIDispatcher.BeginInvoke(action);
    }
}

所以在app.xaml.cs里面 我打电话 AppServices.Init(new DispatcherWrapper());

so inside the app.xaml.cs I call AppServices.Init(new DispatcherWrapper());

在单元测试中,我称之为 AppServices.Init(Substitute.For());

and in the unit tests I call AppServices.Init(Substitute.For());

使用NSubstitute

using NSubstitute

如果您有什么遗漏的地方,请发表评论,我担心如何制作模拟框架来运行我以前在

Please comment if you thing I'm missing something, I'm worried about how do I make the mocking framework to run the actions I used to do inside the

DispatcherHelper.UIDispatcher.Invoke

推荐答案

不幸的是,这种情况是由于最初的设计问题而导致难以对代码库进行单元测试的.创建代码的单元测试的困难与代码的设计水平直接相关.您在帖子中提到的文章是使访问分派器成为可仿真的方法,因为它(分派器)是与UI线程相关联的实现问题,在单元测试期间将不可用,因此您需要做的事情.因此,Invoke

Unfortunately situation is as a result of an initial design issue which made the code base difficult to unit test. The difficulty in creating unit tests for code is directly related to how well the code is designed. The article you mentioned in your post is what you would need to do to make accessing the dispatcher mock-able as it (the dispatcher) is an implementation concern associated with the UI thread which will not be available during your unit tests. Hence the lock on Invoke

引用您提到的文章:

我们无法测试使用 App.Current.Dispatcher 的代码(自 App.Current 在单元测试执行期间将为null.

We are unable to test the code that uses App.Current.Dispatcher (since App.Current will be null during unit tests execution).

一种可能的解决方案是创建一个接口 IDispatcher 和一个 实现该接口的 App.Current.Dispatcher 的包装.

A possible solution would be to create an interface IDispatcher and a wrapper around App.Current.Dispatcher that implements that interface.

public interface IDispatcher {
    void Invoke(Action action);
    void BeginInvoke(Action action);
}

public class DispatcherWrapper : IDispatcher {
    Dispatcher dispatcher;

    public DispatcherWrapper() {    
        dispatcher = Application.Current.Dispatcher;        
    }
    public void Invoke(Action action) {
        dispatcher.Invoke(action);
    }

    public void BeginInvoke(Action action) {
        dispatcher.BeginInvoke(action);
    }
}

这篇关于MVVM light Dispatcher单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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