How to Unit Test BeginInvoke on an Action

微笑、不失礼 提交于 2019-12-03 06:48:09

Abstract your code so that you can inject the behavior you want at testing time.

public class MethodInvoker
{
    public virtual void InvokeMethod(Action method, Action callback)
    {
         method.BeginInvoke(callback, method);
    }
}

This version is asynchronous. At testing time, you can simply make a blocking version:

public class TestInvoker
{
    public IAsyncResult MockResult { get; set; }

    public override void InvokeMethod(Action method, Action callback)
    {
         method();
         callback(MockResult);
    }
}

Then your code simply changes to this:

 // Inject this dependency
Invoker.InvokeMethod(PopulateView, PopulateViewCallback);

At runtime, it's asynchronous. At testing time, it blocks the call.

BeginInvoke() returns an IAsyncResult which you can use to wait.

IAsynchResult ar = action.BeginInvoke(...);
ar.AsyncWaitHandle.WaitOne();

You don't need to check that methods are called instead test the end result - in this case that _view.Propert1 == "xyz".

Because it's an async call you might need to have a loop that Asserts periodically that the value has been set, also a timeout on the test or the check is a must otherwise your test would never fail (just stuck).

You might consider stubbing out the action (PopulateView) in order to skip the Sleep.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!