配置NSubstitute模拟ValidateAndThrowAsync抛异常时单元测试失败求助
The error occurs because you’re combining argument matching (Arg.Any<Entity>()) with ThrowsAsyncForAnyArgs, which creates a conflict in NSubstitute’s call tracking. ThrowsAsyncForAnyArgs is designed to match any arguments for a method, so using Arg.Any alongside it confuses NSubstitute about which call configuration to apply.
Solution 1: Use ThrowsAsync with Argument Matching
Replace ThrowsAsyncForAnyArgs with ThrowsAsync when you explicitly use Arg.Any to match arguments:
_validator .ValidateAndThrowAsync(Arg.Any<Entity>()) .ThrowsAsync(new ValidationException(string.Empty));
Solution 2: Use ThrowsAsyncForAnyArgs without Explicit Argument Matching
If you want to match any call to ValidateAndThrowAsync regardless of arguments, omit Arg.Any and use a dummy parameter (like default) in the method call:
_validator .ValidateAndThrowAsync(default) .ThrowsAsyncForAnyArgs(new ValidationException(string.Empty));
Corrected Full Code
Here’s the fixed version using Solution 1:
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>>(); // Fixed configuration here _validator .ValidateAndThrowAsync(Arg.Any<Entity>()) .ThrowsAsync(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 { } }
This properly configures the substitute to throw a ValidationException when ValidateAndThrowAsync is called with any Entity, resolving the NSubstitute call tracking error.
内容的提问来源于stack exchange,提问作者Erik Philips

