[英]Unit test for asynchronous delegate call in c#
I have a function which created a delegated and starts BeginInvoke on that object, with another function being passed in to wait for EndInvoke: 我有一个函数,该函数创建了一个委托并在该对象上启动BeginInvoke,并传递了另一个函数以等待EndInvoke:
private static void DeploymentComponentThreadedCallBack(IAsyncResult ar)
{
var result = (AsyncResult)ar;
var pluginExecuteAction = (Action<int, Guid, int, EnvironmentServerComponentSet, string>)result.AsyncDelegate;
pluginExecuteAction.EndInvoke(ar);
//report back to WCF service that thread is finished
}
public void DeployComponent(byte[] resource, Guid componentGuid, string deploymentType, Dictionary<string, object> args)
{
var asyncCallback = new AsyncCallback(DeploymentComponentThreadedCallBack);
IDeployComponent plugin = GetPluginDelegate();
Action<byte[], Guid, string, Dictionary<string, object>> pluginExecuteAction = plugin.DeployComponent;
IAsyncResult ar = pluginExecuteAction.BeginInvoke(resource, componentGuid, deploymentType, args, asyncCallback, null);
}
I'd like to unit test this, but when I do so, DeploymentComponentThreadedCallBack never gets hit, and obviously neither does the EndInvoke call. 我想对此进行单元测试,但是当我这样做时,DeploymentComponentThreadedCallBack永远不会受到攻击,并且EndInvoke调用显然也不会受到攻击。 I presume this is happening because the test passes before the asynchronous thread ends, so the thread stops executing before EndInvoke, but is there a way I can stop this happening so I can see that EndInvoke gets hit? 我认为这是由于测试在异步线程结束之前通过而导致的,所以线程在EndInvoke之前停止执行,但是有什么办法可以阻止这种情况的发生,以便我可以看到EndInvoke被击中了吗?
Cheers, Matt 干杯,马特
I think your basic problem is that you're not exposing anything on the DeployComponent
method that would let you track the asynchronous operation that you're starting there. 我认为您的基本问题是,您没有在DeployComponent
方法上公开任何可让您跟踪从此处开始的异步操作的内容。 If you returned the IAsyncResult
from there you could call ar.AsyncWaitHandle.WaitOne()
to wait until it completed. 如果从那里返回IAsyncResult
,则可以调用ar.AsyncWaitHandle.WaitOne()
等待其完成。
As far as I remember the AsyncResult has a flag ( IsCompleted ) that tells you whether the operation is going on. 据我所记得, AsyncResult有一个标志( IsCompleted ),该标志告诉您操作是否正在进行。 Wait on it (eg primitively with a while loop), and then do your assertions 等待它(例如,最初使用while循环),然后执行断言
You simply need to make an injection point to turn asynchrounous calls into blocking calls. 您只需要做一个注入点,即可将非正常通话变成阻塞通话。 For example: 例如:
public class MethodInvoker
{
public virtual void Invoke(Action begin, Action<IAsyncResult> end)
{
begin.BeginInvoke(end, null);
}
}
With a unit testing version like so: 使用这样的单元测试版本:
public class SynchronousInvoker : MethodInvoker
{
public override void Invoke(Action begin, Action<IAsyncResult> end)
{
begin();
end();
}
}
Then you would write code like so: 然后,您将像这样编写代码:
_myMethodInvoker.Invoke(pluginExecuteAction, asyncCallback);
Which in the context of your normal functionality, is asynchronous. 在您的正常功能范围内,这是异步的。 In your unit tests, you simply inject the SynchronousInvoker in it's place and it becomes a blocking call. 在单元测试中,您只需在其位置注入SynchronousInvoker,它就会成为阻塞调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.