I have this code "dummied" down to it most basic parts but I'm not sure how to resolve the the unit test fails. Mostly because the error message suggestion doesn't match what I'm actually doing.
using System;
using System.Threading.Tasks;
using FluentValidation;
using NSubstitute;
using NSubstitute.ExceptionExtensions;
using FluentAssertions;
public class Program
{
private IValidator<Entity> _validator;
public static async Task Main()
{
var program = new Program();
await program.Test();
}
public async Task Test()
{
var entity = new Entity();
_validator = Substitute.For<IValidator<Entity>>();
_validator
.ValidateAndThrowAsync(Arg.Any<Entity>())
.ThrowsAsyncForAnyArgs(new ValidationException(string.Empty));
var testMethod = async () => await CreateAsync(entity);
await testMethod.Should().ThrowAsync<ValidationException>();
}
public async Task CreateAsync(Entity entity)
{
await _validator.ValidateAndThrowAsync(entity);
}
public class Entity {}
}
Returns an exception/stack trace:
Unhandled exception. NSubstitute.Exceptions.CouldNotSetReturnDueToMissingInfoAboutLastCallException: Could not find information about the last call to return from.
Make sure you called Returns() after calling your substitute (for example: mySub.SomeMethod().Returns(value)), and that you are not configuring other substitutes within Returns() (for example, avoid this: mySub.SomeMethod().Returns(ConfigOtherSub())).
If you substituted for a class rather than an interface, check that the call to your substitute was on a virtual/abstract member. Return values cannot be configured for non-virtual/non-abstract members.
Correct use: mySub.SomeMethod().Returns(returnValue);
Potentially problematic use: mySub.SomeMethod().Returns(ConfigOtherSub()); Instead try: var returnValue = ConfigOtherSub(); mySub.SomeMethod().Returns(returnValue);
at NSubstitute.Core.ThreadLocalContext.LastCallShouldReturn(IReturn value, MatchArgs matchArgs) at NSubstitute.SubstituteExtensions.ConfigureReturn[T](MatchArgs matchArgs, Func'2 returnThis, Func'2[] returnThese) at NSubstitute.SubstituteExtensions.ReturnsForAnyArgs[T](T value, Func'2 returnThis, Func'2[] returnThese) at NSubstitute.ExceptionExtensions.ExceptionExtensions.ThrowsAsyncForAnyArgs(Task value, Exception ex) at Program.Test() at Program.Main() at Program.()
Took me a darn while to figure this out but I looked at the signature for
ValidateAndThrowAsync():There is no return value. To configure a void (
Task<void>) returning (async) method, I have to use the When/Do:DotNetFiddle Fixed