c# - 如何在单元测试期间跳过 Fluent 验证静态函数?

标签 c# unit-testing .net-core moq xunit

我正在使用带有 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);
        }
    }

Source

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/

相关文章:

c# - 人们可以编写一个使用 Lambda 表达式的方法吗?

c# - File.Exists(file) 为假但文件存在

c# - 无法使用内容同步操作 (syncrepl) 从 OpenLDAP 服务器获取已删除的项目

.net-core - swagger-document-override/md-override-loader - 失败

c# - 使用 MahApps Metro 主题 VS2013

c# - 仅将 ASP.NET MVC 应用程序管理站点锁定到 LocalHost

objective-c - 对 Objective-C 代码进行单元测试的最佳方法是什么?

C# 单元测试资源

angularjs - Jasmine:为什么 beforeEach() 在嵌套描述中工作,而 beforeAll() 没有?

c# - 无法从后台运行的进程中读取 STDOut