-
Notifications
You must be signed in to change notification settings - Fork 731
Closed
Labels
Description
Description
This is, for all intents and purposes, a feature request.
I would like to use ExecutionTimeOf() (or, even better, ExecutionTime() directly) with Func<Task> in addition to the usual Action, so that I can easily check the behavior of time-sensitive awaitable methods.
Currently I have to circumvent this problem through the use of System.Diagnostics.Stopwatch, which I think is a suboptimal solution since it takes me out of the level of abstraction I would like to be at when composing unit tests - and even more so when composing scenarios.
Complete minimal example reproducing the issue
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using FluentAssertions;
using FluentAssertions.Extensions;
using Xunit;
namespace Yet.Another.FeatureRequest
{
public class ProofOfConcept
{
[Fact]
public async Task TimingAnAsyncMethod_CurrentlyRequiresAStopWatch()
{
// ARRANGE
var testee = new Testee(5.Seconds());
var time = new Stopwatch();
// ACT (more or less)
Func<Task> action = async () =>
{
time.Start();
await testee.SomeMethodAsync();
time.Stop();
};
// ASSERT
action.Should().NotThrow();
time.Elapsed.Should().BeCloseTo(
testee.Delay, 1.Seconds(),
"I'm generous when it comes to async timing");
}
}
public class Testee
{
public TimeSpan Delay { get; }
public Testee(TimeSpan delay) => Delay = delay;
public async Task SomeMethodAsync() => await Task.Delay(Delay);
}
}Expected behavior:
Several versions come to mind, such as
// ACT (or somesuch)
Func<Task> action = async () => await testee.SomeMethodAsync();
// ASSERT
action.Should().NotThrow();
action.ExecutionTime().Should().BeCloseTo(testee.Delay, 1.Seconds());
// which is obviously bad due to double execution...or
// ACT (sort of)
Action action = () => testee.ExecutionTimeOf(async _ => await _.SomeMethodAsync())
.Should().BeCloseTo(testee.Delay, 1.Seconds());
// ASSERT
action.Should().NotThrow();or
// ACT (kinda)
Func<Task> action = async () => await testee.ExecutionTimeOf(_ => _.SomeMethodAsync())
.Should().BeCloseTo(testee.Delay, 1.Seconds());
// ASSERT
action.Should().NotThrow();Actual behavior:
ExecutionTimeis an extension Method ofAction- so... no dice.Async lambda expressions cannot be converted to expression trees, apparentlyExecutionTimeOfcannot handleTaskorTask<T>differently and especially cannot provide an awaitable object
Versions
FluentAssertions v5.3.2
xunit v2.3.1
.Net Core v2.1.0
TadeuszSobol