private async Task WaitForHandlerCompletion(WaitForResult waitForResult, int timeoutInMs)
 {
     using (Timer timer = new Timer(new TimerCallback(TimedOutCallback), waitForResult, timeoutInMs, Timeout.Infinite))
     {
         while (!waitForResult.HasCompleted && !waitForResult.HasTimedOut)
         {
             await Task.Delay(100);
         }
     }
 }
        public async Task <WaitForResult> WaitFor <T>(
            Func <Task> func,
            bool assertOnTimeout = true,
            bool assertOnError   = false,
            int timeoutInMs      = 15000)
        {
            var waitForResult = new WaitForResult();

            var hook = _testContext.Hooks.SingleOrDefault(h => h is Hook <T>) as Hook <T>;

            hook.OnReceived  = (message) => { waitForResult.SetHasStarted(); };
            hook.OnProcessed = (message) => { waitForResult.SetHasCompleted(); };
            hook.OnErrored   = (ex, message) => { waitForResult.SetHasErrored(ex); };

            try
            {
                await func();
            }
            catch (Exception ex)
            {
                waitForResult.SetHasErrored(ex);
            }
            await WaitForHandlerCompletion(waitForResult, timeoutInMs);

            if (assertOnTimeout)
            {
                waitForResult.HasTimedOut.Should().Be(false, "handler should not have timed out");
            }

            if (assertOnError)
            {
                waitForResult.HasErrored.Should().Be(false, $"handler should not have errored with error '{waitForResult.LastException?.Message}'");
            }

            return(waitForResult);
        }