I'm trying to create a minimal working example of how the Timeout
parameter in Xunit.net operates. I currently have the following Fact
example, but it isn't operating as I expect, as it fails the test:
[Fact(Timeout = 50)]
public void FactTimeout_TimeoutLessThanProcessingTime_ThrowTestTimeoutException()
{
// Arrange
// Act
Action act = () => Task.Delay(5000);
// Assert
Assert.Throws<TestTimeoutException>(act);
}
Is this correct, or is my understand wrong? Is there something else that needs to be changed or added to the test itself, or the Xunit config?
Based on @RubenBartelink's answer I got the following to work:
// Will generate the exception and display it in the results window
[Fact(Timeout = 50)]
public async void TestOne() => await Task.Delay(5000);
// This will pass the test, but will complain that it is not awaited
[Fact(Timeout = 50)]
public void TestTwo() => Assert.ThrowsAsync<TestTimeoutException>(() => Task.Delay(5000));
You likely mean to use Assert.ThrowsAsync
- otherwise you're measuring how long it takes to kick off the task (assuming the 50 means you intend to set a timeout of 50ms and you just want to prove it can indeed fail)
While there are cases where you can avoid it, in general, I make such an async Test Method be async Task ...
and ensure there is an await
in there to make it easier to follow the flow (assuming Async
ness is key to your test)
You may find discussion/examples in https://github.com/xunit/xunit/issues/217 useful
EDIT: Example untested impl per your comment
I'm trying to create a minimal working example of how the Timeout parameter in Xunit.net operates. I currently have the following Fact example, but it isn't operating as I expect, as it fails the test:
[Fact(Timeout = 50)]
public async Task FactTimeout_TimeoutLessThanProcessingTime_ThrowTestTimeoutException()
{
Action act = () => Task.Delay(5000);
// Trigger the timeout by attempting something that will take too long
await act;
}
this should internally result in a test timeout (the TestTimeoutException
you were trying to catch). I suspect there won't be a neat way for you to catch the exception in question - if you need to observe and react to the timeout occurring and do something explicit (which you ideally want to avoid doing in a test), you'll need to explicitly manage that by doing a Task.WhenAny
roughly like this:
public async Task FactTimeout_TimeoutLessThanProcessingTime_ThrowTestTimeoutException()
{
Action act = () => Task.Delay(5000);
let timeoutTask = Task.Delay(50);
let res = await Task.WhenAny(timeoutTask, act);
Assert.IsSame(timeoutTask, res);
}
NB this is only as an example to show that the timeout does happen and can be observed - the former approach with correct awaiting
and letting xUnit manage the timeout without polluting the test with this sort of logic is where you want to arrive at.