I have got a problem in my current WPF project when unit testing with mstest.
In one of my ViewModels i need to use the dispatcher to set something in the view.
While Unit Testing this ViewModel i figured out theAction delegate will never covered.
Unit-Test with Dispatcher and BeginInvoke fails
- [TestMethod()]
- public void TestTheTest1()
- {
- bool myBoolean = false;
- Action theAction = () => myBoolean = true;
- Task.Factory.StartNew(() =>
- Dispatcher.CurrentDispatcher.BeginInvoke(
- DispatcherPriority.Normal,
- theAction));
- Thread.Sleep(500);
- Assert.IsTrue(myBoolean);
- }
Unit-Test with Dispatcher and Invoke succeed
- [TestMethod()]
- public void TestTheTest2()
- {
- bool myBoolean = false;
- Action theAction = () => myBoolean = true;
- Task.Factory.StartNew(() =>
- Dispatcher.CurrentDispatcher.Invoke(
- DispatcherPriority.Normal,
- theAction));
- Thread.Sleep(500);
- Assert.IsTrue(myBoolean);
- }
So i handled this by create a Dispatch helper class for myself. This class handle all Dispatcher calls at runtime and for unit-tests.
There are also other solutions to handle this problem.
Solution with DispatcherFrame
- [TestMethod()]
- public void TestTheTest3()
- {
- bool myBoolean = false;
- DispatcherFrame frame = null;
- Action theAction = () =>
- {
- myBoolean = true;
- frame.Continue = true;
- };
- Task.Factory.StartNew(() =>
- {
- Dispatcher.CurrentDispatcher.BeginInvoke(
- DispatcherPriority.Normal,
- theAction);
- Dispatcher.PushFrame(frame);
- });
- Thread.Sleep(500);
- Assert.IsTrue(myBoolean);
- }
Also possible is to use a interface for the dispatcher and to have the posibility to mock the dispatcher.At runtime you can pulling in the interface from your IOC container.
Dispatcher interface
- public interface IDispatcher
- {
- void Dispatch( Delegate method, params object[] args );
- }