我正在使用带有 Moq 的 xunit 并在一个函数中测试其他功能,但我总是从 Fluent Validation 扩展方法中得到一个异常,我无法绕过该异常。
这是原始代码
public class AdService : IAdService
{
private readonly IValidator<AdToSearchDto> _adToSearchDtoValidator;
public AdService(IValidator<AdToSearchDto> addToSearchDtoValidator)
{
_adToSearchDtoValidator = addToSearchDtoValidator
}
public async Task<AdsToReturnDto> GetAdsAsync(AdToSearchDto searchDto)
{
_adToSearchDtoValidator.ValidateAndThrow(searchDto); // This line always throw exception
return await _adRepository.GetUserAdsAsync(searchDto, userId, user?.Country);
}
}
单元测试类
[Fact]
public async Task Ads_Can_Searched_By_UserId()
{
var validator = new Mock<IValidator<AdToSearchDto>>();
var adService = new AdService(validator.Object);
var adService = new AdService(validator.Object );
var ads = DataGenerator.CreateAds(2);
ads[0].UserId = searchingUserId;
ads[1].UserId = anotherUserId;
await adRepository.CreateAdAsync(ads[0]);
await adRepository.CreateAdAsync(ads[1]);
var result = await adService.GetAdsAsync( adToSearchDto, Guid.Empty ) ;
result.Ads.Count.Should().Be(1);
result.Ads.FirstOrDefault()?.UserId.Should().Be(searchingUserId.ToString());
}
我无法绕过
ValidateAndThrow
因为这是扩展方法。
有没有办法绕过单元测试中的ValidateAndThrow方法?
编辑:
我遇到错误
System.NullReferenceException : Object reference not set to an instance of an object.
at FluentValidation.DefaultValidatorExtensions.ValidateAndThrow[T](IValidator`1 validator, T instance, String ruleSet) in C:\Projects\FluentValidation\src\FluentValidation\DefaultValidatorExtensions.cs:line 943
at Market.Business.Ad.AdService.GetAdsAsync(AdToSearchDto searchDto, Guid userId) in C:\Users\Shahid Abdullah\Projects\MyStuff.IdentityServer\src\Market\Market.Business\Ad\AdService.cs:line 129
at Market.Test.Ad.AdTests.Ads_Can_Searched_By_UserId() in C:\Users\Shahid Abdullah\Projects\MyStuff.IdentityServer\src\Market\Market.Test\Ad\AdTests.cs:line 100
--- End of stack trace from previous location where exception was thrown ---
源代码异常
public static void ValidateAndThrow<T>(
this IValidator<T> validator,
T instance,
string ruleSet = null)
{
ValidationResult validationResult = validator.Validate<T>(instance, (IValidatorSelector) null, ruleSet);
if (!validationResult.IsValid) // this line throws exception as validationResult is null
throw new ValidationException((IEnumerable<ValidationFailure>) validationResult.Errors);
}
最佳答案
/// <summary>
/// Performs validation and then throws an exception if validation fails.
/// </summary>
/// <param name="validator">The validator this method is extending.</param>
/// <param name="instance">The instance of the type we are validating.</param>
/// <param name="ruleSet">Optional: a ruleset when need to validate against.</param>
public static void ValidateAndThrow<T>(this IValidator<T> validator, T instance, string ruleSet = null) {
var result = validator.Validate(instance, ruleSet: ruleSet);
if (!result.IsValid) {
throw new ValidationException(result.Errors);
}
}
ValidateAndThrow
期望在调用时从验证器返回结果。
因为模拟没有结果
if (!result.IsValid) {...
抛出空引用异常。
将模拟设置为在执行测试时调用扩展方法时按预期运行
[Fact]
public async Task Ads_Can_Searched_By_UserId() {
//Arrange
var validator = new Mock<IValidator<AdToSearchDto>>();
var validResult = new ValidationResult();
validator
.Setup(_ => _.Validate(It.IsAny<ValidationContext>())
.Returns(validResult);
var adService = new AdService(validator.Object);
//...
}
关于c# - 如何在单元测试期间跳过 Fluent 验证静态函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58450291/