Я использую библиотеку Mediatr для регистрации и вызова своих RequestHandlers. Все шло нормально, пока я не начал читать больше об интегрированных тестах.
ПОЖАЛУЙСТА, КРАСНЫЙ ПОСЛЕ РЕДАКТИРОВАНИЯ
Я не могу вызвать свой класс, унаследованный от RequesHandler.
Мой класс выглядит так:
public class MyRequestHandler : RequestHandler<MyRequest, MyResponse>
{
....
}
Я не использую Meditr async, а использую .net framework 4.7 вместо ядра asp.net, поэтому все, что я выгляжу, возвращает мне ответы для ядра asp.net.
Когда я конструирую MyTestClass
, чтобы построить RequestHandler
, мне нужно создать ServiceFactory
, и, возможно, это проблема, потому что я не знаю, как это сделать.
public MyClassTest()
{
ServiceFactory sv = null;
_mediator = new Mediator(sv);
}
ИЗМЕНИТЬ
Предоставление дополнительной информации
У меня есть этот обработчик на уровне приложения
public class LogInUserByFormHandler : RequestHandler<LogInUserByFormRequest, LogInUserByFormResponse>
{
private readonly IValidator<LogInUserByFormRequest> _validator;
public LogInUserByFormHandler(IValidator<LogInUserByFormRequest> validator)
{
_validator = validator;
}
protected override LogInUserByFormResponse Handle(LogInUserByFormRequest request)
{
_validator.ValidateAndThrow(request);
var userInfo = GetUserInfo(request);
ValidateLogInUserByFormRules(userInfo);
var userLoginInfo = GetValidUserLoginInfo(request);
ValidateUserLoginInfoByFormRules(userLoginInfo);
var sessionKey = CreateUserSessionKey(userInfo);
var response = new LogInUserByFormResponse
{
UserName = request.UserName,
SessionKey = sessionKey,
UserId = userInfo.id_usuario
};
return response;
}
//A LOT OF CODE HERE, methods and etc
}
Как можно видеть, он реализует Mediatr. В моем веб-проекте на уровне презентации я использовал AutoFac для внедрения обработчиков, поэтому любой запрос, который я делаю, всегда обрабатывается правильным методом. Все, что мне нужно сделать, это позвонить, вот так:
var logInByFormRequest = new LogInUserByFormRequest
{
UserName = viewModel.UserName,
Password = viewModel.Password
};
var response = _mediator.Send(logInByFormRequest).Result;
Это работает как шарм. Теперь проблема находится в тестовом проекте. Он ссылается на приложение так же, как и проект презентации. Я не знаю, как заставить mediator.send найти правильный метод.
РЕДАКТИРОВАТЬ²
Вот мой тестовый код
[TestClass]
public class LogInUserByFormTest
{
private LogInUserByFormRequest CreateRequest(string userName, string password)
{
LogInUserByFormRequest request = new LogInUserByFormRequest
{
UserName = userName,
Password = password
};
return request;
}
[TestMethod]
[Description("")]
public void UserName_ShouldHave_Max_30Characters_Exception()
{
try
{
var request = CreateRequest("UserNameIsGreaterThanAllowed", "password");
var mediator = new Mock<IMediator>();
var response = mediator.Object.Send(request).Result;
}
catch (System.Exception ex)
{
throw;
}
}
}
Результат (ответ) всегда равен нулю, и посредник не вызывает правого обработчика.
РЕДАКТИРОВАТЬ3
Вот как я регистрирую обработчики и валидаторы. Пользуюсь автофаком. Этот класс здесь вызывается в global.asax
public class AutofacConfig
{
public static void ConfigureContainer()
{
var builder = new ContainerBuilder();
builder.RegisterControllers(Assembly.GetExecutingAssembly()).InstancePerRequest();
builder.RegisterType<Mediator>().As<IMediator>().InstancePerLifetimeScope();
builder.RegisterType<AutofacValidatorFactory>().As<IValidatorFactory>().SingleInstance();
builder.RegisterType<FluentValidationModelValidatorProvider>().As<ModelValidatorProvider>();
builder.RegisterType<RegistryManagerService>().As<IRegistryManagerService>().SingleInstance().WithParameter("appName", ConfigurationManager.AppSettings["APPNAME"]);
builder.Register<ServiceFactory>(context =>
{
var c = context.Resolve<IComponentContext>();
return t => c.Resolve(t);
});
builder.RegisterAssemblyTypes(Assembly.Load("Docspider.Application"))
.Where(x => x.Name.EndsWith("Handler"))
.AsImplementedInterfaces();
builder.RegisterAssemblyTypes(Assembly.Load("Docspider.Application"))
.Where(x => x.Name.EndsWith("Validator"))
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
}
}
public class AutofacValidatorFactory : ValidatorFactoryBase
{
private readonly IComponentContext _context;
public AutofacValidatorFactory(IComponentContext context)
{
_context = context;
}
public override IValidator CreateInstance(Type validatorType)
{
if (_context.TryResolve(validatorType, out object instance))
{
var validator = instance as IValidator;
return validator;
}
return null;
}
}