Search code examples
c#fluent-assertions

How can I assert the duration of the synchronous part of an async call?


I need to assert that the initial synchronous part of an async method executes within a certain duration. Is this possible with fluent assertions? I also need to assert the minimum and maximum total duration (eg, using CompleteWithinAsync and NotCompleteWithinAsync), so the solution needs to cover all three timings (see my other question How do I assert that an async task should complete within a minimum and maximum time?) on a single task call/await expression.


Solution

  • The trivial and contrived, seems to function as expected.

    using System;
    using System.Diagnostics;
    using System.Threading;
    using System.Threading.Tasks;
    using FluentAssertions;
                        
    public class Program
    {
        public static async Task Main()
        {
            // Arrange
            static async Task someAsyncBehaviourMock()
            {
                await Task.Yield();
                await Task.Delay(1000);
            };
            
            var s1 = Stopwatch.StartNew();
            var s2 = Stopwatch.StartNew();
            // Act
            var task = Target(someAsyncBehaviourMock);
            s1.Stop();
            await task;
            s2.Stop();
            
            // Assert
            s1.ElapsedMilliseconds.Should().BeGreaterThan(1000).And.BeLessThan(2000);
            s2.ElapsedMilliseconds.Should().BeGreaterThan(2000).And.BeLessThan(3000);
            
            Console.WriteLine(
                $"Success. s1:{s1.ElapsedMilliseconds}, s2:{s2.ElapsedMilliseconds}");
        }
        
        private static async Task Target(Func<Task> someAsyncBehaviour)
        {
            // Initial Sync Behaviour
            Thread.Sleep(1000);
            
            // Injected Async Behaviour
            await someAsyncBehaviour();
        }
    }