带有Moq的单元测试FluentValidator验证器

时间:2019-04-29 09:31:03

标签: .net-core moq autofac fluentvalidation

我正在尝试编写与我使用的(自定义)提供的框架一起使用的单元测试。所以我想做的是使用此处提供的QueryDispatcher将错误翻译输出到数据库中(正在进行中,据我所知可能更好):

public Task<TModel> ExecuteAsync<TModel>(IQuery<TModel> query)
{
    var validatorType = typeof(IValidator<>).MakeGenericType(query.GetType());

    if (componentContext.TryResolve(validatorType, out object instance))
    {
        var validator = instance as IValidator;
        var result = validator.Validate(query); ///<-- THIS LINE IS NULL

        if (result != null && !result.IsValid)
        {
            List<TranslationQueryModel> errors = new List<TranslationQueryModel>();

            foreach (var item in result.Errors)
            {
                var message = item.ErrorMessage.Split('.');
                string lang = ((ClaimsIdentity)contextAccessor.HttpContext.User.Identity).Claims.SingleOrDefault(s => s.Type == "lang")?.Value.ToUpper();

                errors.Add(ExecuteAsync(new GetErrorTranslationQuery()
                {
                    ObjectName = message.First(),
                    ObjectField = $"{message[1]}.{message[2]}",
                    Language = lang
                }).Result);
            }

            throw new ApplicationException(JsonConvert.SerializeObject(errors));
        }

#if DEBUG
        Debug.WriteIf(result == null, $"Did you forget a validator for {typeof(TModel).Name}?");
#endif
    }

    var queryHandlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TModel));

    var handler = componentContext.Resolve(queryHandlerType);

    return (Task<TModel>)queryHandlerType
        .GetMethod("HandleAsync")
        .Invoke(handler, new object[] { query });
}

接下来我要在单元测试中尝试的是以下

[Fact]
public async Task get_schedule_without_securable_should_show_error()
{
    var request = GetScheduleRequestOk();
    request.Securable = Securable.None;
    var controllerContext = FakeControllerContext(Configuration);

    var queryDispatcher = new Mock<QueryDispatcher>(ComponentContext, ContextAccessor).As<IQueryDispatcher>();
    queryDispatcher.Setup(q => q.ExecuteAsync(It.IsAny<GetScheduleListQuery>()))
    .Throws(new ApplicationException(JsonConvert.SerializeObject(new List<TranslationQueryModel>()
    {
        new TranslationQueryModel()
        {
            Error = "GetScheduleListQuery.ErrorMessage.SecurableIsNull"
        }
    })));

    var cache = new MemoryCache(new MemoryCacheOptions());

    _scheduleController = new ScheduleController(queryDispatcher.Object, cache)
    {
        ControllerContext = controllerContext
    };

    var response = await _scheduleController.GetSchedules(request);

    response.Should().BeOfType(typeof(BadRequestObjectResult));
}

所以我的问题是,是否始终需要将带有QueryDispatcher模拟的模拟查询结果传递给“测试”,以便正确显示错误,因为它实际上未命中Validator中的代码,也未显示错误正确地。如果有人能指出我正确的方向,那就太好了。

0 个答案:

没有答案