我正在尝试编写与我使用的(自定义)提供的框架一起使用的单元测试。所以我想做的是使用此处提供的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中的代码,也未显示错误正确地。如果有人能指出我正确的方向,那就太好了。