Home > Software engineering >  xUnit does not accept synchronous Throws with method that returns Task<>
xUnit does not accept synchronous Throws with method that returns Task<>

Time:09-23

I am writing a unit test for a method that returns a Task<>, but is not async. Still xUnit.net wants me to use ThrowsAsync to check for thrown exceptions:

Error CS0619 'Assert.Throws(Func)' is obsolete: 'You must call Assert.ThrowsAsync (and await the result) when testing async code.'

The method returns a Task<> because it is an implementation of an interface, where some implementations do indeed run async.

This is the interface:

public interface IPtlCommand
{
    Task<PtlResult> Execute(string[] args);
}

and the implementation:

public class SetTag : IPtlCommand
{
    public Task<PtlResult> Execute(string[] args)
    {
        return Task.FromResult<PtlResult>(new PtlResult());
    }
}
     

my test code (that gives the compiler error):

[Fact]
public void SetTag_ThrowsArgumentExceptionWhenNoTag()
{
    var command = new SetTag();

    // act & assert
    Assert.Throws<ArgumentException>(() => command.Execute(new string[] { "host" }));
}   

other tests on the command.Execute call do work correctly, also without await.

CodePudding user response:

If you are using Visual Studio, it'll suggest a Quick Action to fix the issue. If you ask it to implement that suggestion, it'll change the test:

[Fact]
public async Task SetTag_ThrowsArgumentExceptionWhenNoTag()
{
    var command = new SetTag();

    // act & assert
    await Assert.ThrowsAsync<ArgumentException>(
        () => command.Execute(new string[] { "host" }));
}

This test now compiles (and fails, since Execute doesn't throw an exception).

  • Related