11

Some mistake in a code test rise this question, due the extension of the code, here is a complete project that replicates exactly the problem we have (to save you analyzing tons of lines).

The issue is when trying to catch an exception from an asynchronous method, here the AsyncTest.cs file:

using System;
using Xunit;

namespace AsyncTest
{
    public class AsyncTest
    {
        [Fact]
        public void ProbeTest()
        {
            // Arrange
            var probe = new Probe();

            // Act
            Action action = async () =>
                await probe.GetJob();

            // Assert
            var ex = Assert.Throws<InvalidOperationException>(action);
            Assert.Contains("Trouble with Project.", ex.Message);
        }
    }
}

Now, the Probe.cs class to be tested (Note the delay and the exception throwing in GetById method called by the GetJob method):

using System;
using System.Threading.Tasks;

namespace AsyncTest
{
    class Probe
    {
        public async Task<MyResult<Guid>> GetJob()
        {
            var etlJob = await GetById("id");
            return new MyResult<Guid>(etlJob);
        }

        public async Task<Guid> GetById(string id)
        {
            await Task.Delay(200);

            throw new InvalidOperationException("Trouble with Project.");
        }
    }
}

Last, the MyResult.cs class used by Probe.cs.

namespace AsyncTest
{
    public class MyResult<T>
    {
        private T _value;

        public MyResult(T Value)
        {
            _value = Value;
        }

        public string Message { get; set; }
        public T Data { get; set; }
    }
}

Apparently, the test ends before the exception is thrown even if the await Task.Delay(200); line is removed. In some cases using multiple breakpoints and placing the call in a loop, an exception is throw but not detected by the test.

It looks like a synchronous and asynchronous mix-up but can't figure out exactly what.

Thanks in advance.

1 Answer 1

16

Make your test method asynchronous and await the assertion:

[Fact]
public async Task ProbeTest()
{
    // Arrange
    var probe = new Probe();

    // Act
    Func<Task> action = async () => await probe.GetJob();

    // Assert
    var ex = await Assert.ThrowsAsync<InvalidOperationException>(action);
    Assert.Contains("Trouble with Project.", ex.Message);
}
Sign up to request clarification or add additional context in comments.

2 Comments

Great !!!, Thanks. Is well know that async exceptions are registered into the task but did not figure out how to handle it.
This can also be a test for you based on this solution changing the Assert statement >> Assert.IsType<InvalidOperationException>(ex);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.