Модульный тест для асинхронного вызова делегата в c # - PullRequest
1 голос
/ 31 августа 2011

У меня есть функция, которая создала делегированный и запускает 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);
}

Я хотел бы выполнить это модульное тестирование, но когда ясделать это, DeploymentComponentThreadedCallBack никогда не получает удар, и, очевидно, также не вызывает EndInvoke.Я предполагаю, что это происходит, потому что тест проходит до завершения асинхронного потока, поэтому поток прекращает выполнение до EndInvoke, но есть ли способ, которым я могу остановить это, чтобы я мог видеть, что EndInvoke получает удар?

Cheers,Matt

Ответы [ 3 ]

1 голос
/ 31 августа 2011

Я думаю, что ваша основная проблема в том, что вы не выставляете ничего в методе DeployComponent, который позволил бы вам отслеживать асинхронную операцию, которую вы там начинаете. Если вы вернули IAsyncResult оттуда, вы можете позвонить ar.AsyncWaitHandle.WaitOne() и дождаться его завершения.

0 голосов
/ 31 августа 2011

Вам просто нужно создать точку внедрения, чтобы превратить асинхронные вызовы в блокирующие вызовы.Например:

 public class MethodInvoker
 {
     public virtual void Invoke(Action begin, Action<IAsyncResult> end)
     {
          begin.BeginInvoke(end, null);
     }
 }

С версией модульного тестирования, например, так:

 public class SynchronousInvoker : MethodInvoker
 {
     public override void Invoke(Action begin, Action<IAsyncResult> end)
     {
         begin();
         end();
     }
 }

Тогда вы бы написали такой код:

 _myMethodInvoker.Invoke(pluginExecuteAction, asyncCallback);

Что в контекстевашей нормальной функциональности, является асинхронным.В своих модульных тестах вы просто внедряете SynchronousInvoker на его место, и он становится блокирующим вызовом.

0 голосов
/ 31 августа 2011

Насколько я помню, AsyncResult имеет флаг ( IsCompleted ), который сообщает вам, происходит ли операция. Подождите его (например, примитивно с циклом while), а затем сделайте ваши утверждения

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...