在单元测试中使用WPF调度正确的方法 [英] Correct method for using the WPF Dispatcher in unit tests
问题描述
我试图遵循在单元测试中使用WPF调度的建议。为了得到我NUnit测试运行
I am trying to follow the suggestions from Using the WPF Dispatcher in unit tests in order to get my nUnit test to run.
当我写我的单元测试如下,它的工作原理:
When I write my unit test as below, it works:
[Test]
public void Data_Should_Contain_Items()
{
DispatcherFrame frame = new DispatcherFrame();
PropertyChangedEventHandler waitForModelHandler = delegate(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == "Data")
{
frame.Continue = false;
}
};
_myViewModel.PropertyChanged += waitForModelHandler;
Dispatcher.PushFrame(frame);
Assert.IsTrue(_myViewModel.Data.Count > 0, "Data item counts do not match");
}
不过,如果我尝试使用DispatcherUtil的建议,这不工作方式:
However, if I try to use the suggestion of the DispatcherUtil, it does not work:
[Test]
public void Data_Should_Contain_Items()
{
DispatcherUtil.DoEvents();
Assert.IsTrue(_myViewModel.Data.Count > 0, "Data item counts do not match");
}
public static class DispatcherUtil
{
[SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
public static void DoEvents()
{
DispatcherFrame frame = new DispatcherFrame();
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
new DispatcherOperationCallback(ExitFrame), frame);
Dispatcher.PushFrame(frame);
}
private static object ExitFrame(object frame)
{
((DispatcherFrame)frame).Continue = false;
return null;
}
}
当我使用的是DispatcherUtil,它看起来像来电ExitFrame发生的太快,之前数据已准备好。
When I am using the DispatcherUtil, it looks like the call to ExitFrame happens too soon, before the data is ready.
我这不是正确使用DispatcherUtil?这似乎是一个更好的方法,用来处理调度而不是等待从视图模型的回调。
Am I not using the DispatcherUtil correctly? It seems like a better method to use to handle the dispatcher rather then waiting for callbacks from the view model.
推荐答案
由于调度在单元测试有问题,我的解决办法是打破调度您的视图模型的依赖。我认为像目前你已经硬编码引用:
Since the dispatcher is problematic in unit tests, my solution would be to break your view-model's dependency on the dispatcher. I assume that currently you have hard coded references like:
Dispatcher.CurrentDispatcher.BeginInvoke(..
调度程序是一个外部的依赖,不应该是你的单元测试的一部分 - 我们可以假设调度作品
The dispatcher is an external dependency and shouldn't be part of your unit tests - we can assume the dispatcher works.
我会使用依赖注入(无论是穷人芒,团结,等等)。
创建一个合适的接口代表调度。
创建一个真正的实现它包装真正的调度员
创建一个使用Action.BeginInvoke
在假你记录所有IAsyncResults返回调用的BeginInvoke假执行。结果
然后有一个辅助方法,这将等待所有调用完成后,你可以在你的测试中使用,以等待完成。
I would use dependency injection (either poor mans, Unity, etc).
Create a suitable interface representing the dispatcher.
Create a real implementation which wraps the real dispatcher.
Create a fake implementation which uses Action.BeginInvoke.
In the fake you record all IAsyncResults returned to calls to BeginInvoke.
Then have a helper method which would wait for all calls to completed which you can use in your test to wait for completion.
或者有一个视图模型基类,它做同样的事情。调用调度正常,但可直接调用在测试过程中假的。
Or have a view model base class which does the same thing. Calls the dispatcher normally but can be directed to call a fake during tests.
这篇关于在单元测试中使用WPF调度正确的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!