Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FluentAssertions ShouldNotThrow is not recognised for an async method/Func

I am trying to check an async method throws concrete exception.

For that I am using MSTEST and FluentAssertions 2.0.1.

I have checked this Discussion on Codeplex and to see how it works with async-exception methods this another one link about FluentAssertions async tests:

After a while trying to work with my 'production' code I have switched off to the Fluentassertions fake aync class and my resulting code is like this (put this code inside a [TestClass]:

[TestMethod]
public void TestThrowFromAsyncMethod()
{
    var asyncObject = new AsyncClass();
    Action action = () =>
    {
        Func<Task> asyncFunction = async () =>
        {
            await asyncObject.ThrowAsync<ArgumentException>();
        };
        asyncFunction.ShouldNotThrow();
    };
}


internal class AsyncClass
{
    public async Task ThrowAsync<TException>()
        where TException : Exception, new()
    {
        await Task.Factory.StartNew(() =>
        {
            throw new TException();
        });
    }

    public async Task SucceedAsync()
    {
        await Task.FromResult(0);
    }
}

The problem is that ShouldNotThrow is not valid:

ShouldNotThrow method is not recognised by the code. If I try to compile, it gives me this error: 'System.Func' does not contain a definition for 'ShouldNotThrow' and the best extension method overload 'FluentAssertions.AssertionExtensions.ShouldNotThrow(System.Action, string, params object[])' has some invalid arguments

Thanks.


SOLUTION

2.0.1 FA version doesn't support this ShouldNotThrow functionality and it will be included in the next reléase 2.1 (near next week).

Note: ShouldThrow is already supported in 2.0.1 versión.

like image 368
ferpega Avatar asked Aug 14 '13 19:08

ferpega


2 Answers

You don't need the encompassing Action. That is only used in the unit tests to verify that the API is throwing the right exception. This should be sufficient:

[TestMethod]
public void TestThrowFromAsyncMethod()
{
    Func<Task> asyncFunction = async () =>
    {
        await asyncObject.ThrowAsync<ArgumentException>();
    };

    asyncFunction.ShouldNotThrow();
}

Unfortunately the ShoudlNotThrow() on a Func is missing from .NET 4.5. I've fixed this in release 2.1 (currently dogfooding).

like image 66
Dennis Doomen Avatar answered Oct 02 '22 12:10

Dennis Doomen


If you look at AssertionExtensions.cs class you will see that the ShouldNotThrow extension method on Func is only defined for net45 or winrt compilation targets.

Check this:

  1. Your unit tests project is on .net 4.5 or winrt
  2. The referenced assertion library is the .net 4.5 one, if not try changing the referenced FluentAssertions library to the right one.

Also after doing this, I think you need to call the action method to do the assertion, otherwise the inner lambda will not be called:

[TestMethod]
public void TestThrowFromAsyncMethod()
{
    var asyncObject = new AsyncClass();
    Action action = () =>
    {
        Func<Task> asyncFunction = async () =>
        {
            await asyncObject.ThrowAsync<ArgumentException>();
        };
        asyncFunction.ShouldNotThrow();
    };

    action.ShouldNotThrow();
}
like image 33
Iñaki Elcoro Avatar answered Oct 02 '22 12:10

Iñaki Elcoro