如何在 .net framework 4.7 上使用 Mediatr 进行集成测试?

How to do Integration Tests with Mediatr on .net framework 4.7?

我正在使用 Mediatr 库注册和调用我的 RequestHandlers。 一切都很顺利,直到我开始阅读有关集成测试的更多信息。

编辑后请阅读

我无法调用继承自 RequesHandler 的 class。

我的 class 看起来像这样:

public class MyRequestHandler : RequestHandler<MyRequest, MyResponse>
{
  ....
}

我没有使用 Meditr async,我使用的是 .net framework 4.7 而不是 asp.net 核心,所以,一切看起来都像 returns 我回答 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。 在我的表示层 Web 项目中,我使用 AutoFac 来注入处理程序,因此,我所做的任何请求总是由正确的方法处理。 我所要做的就是像这样打电话:

var logInByFormRequest = new LogInUserByFormRequest
{
    UserName = viewModel.UserName,
    Password = viewModel.Password
};

var response = _mediator.Send(logInByFormRequest).Result;

这很有魅力。现在的问题出在测试项目上。它像演示项目一样引用应用程序。 我不知道如何让 mediator.send 找到正确的方法。

EDIT²

我的测试代码来了

[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;
        }
    }
}

结果(响应)始终为 null,中介未调用正确的处理程序。

EDIT3

这是我注册处理程序和验证程序的方法。 我使用autofac。这里的class是在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;
    }
}

对于这样的集成测试,您需要配置必要的依赖项。既然你已经指出 Autofac 正在被使用,那么就像你在生产环境中那样配置一个容器。使用容器获取中介并执行所需的测试。

例如

[TestClass]
public class LogInUserByForm_IntegrartionTest {
    private LogInUserByFormRequest CreateRequest(string userName, string password) {
        LogInUserByFormRequest request = new LogInUserByFormRequest {
            UserName = userName,
            Password = password
        };

        return request;
    }

    IMediator BuildMediator() {
        //AutoFac
        var builder = new ContainerBuilder();
        builder.RegisterAssemblyTypes(typeof(IMediator).GetTypeInfo().Assembly).AsImplementedInterfaces();

        var mediatrOpenTypes = new[] {
            typeof(IRequestHandler<,>)
        };

        foreach (var mediatrOpenType in mediatrOpenTypes) {
            builder
                .RegisterAssemblyTypes(typeof(LogInUserByFormRequest).GetTypeInfo().Assembly)
                .AsClosedTypesOf(mediatrOpenType)
                .AsImplementedInterfaces();
        }

        builder.Register<ServiceFactory>(ctx => {
            var c = ctx.Resolve<IComponentContext>();
            return t => c.Resolve(t);
        });

        //...all other needed dependencies.

        //...

        var container = builder.Build();

        var mediator = container.Resolve<IMediator>();
        return mediator;
    }

    [TestMethod]
    [Description("")]
    public async Task UserName_ShouldHave_Max_30Characters_Exception() {
        try
        {
            //Arrange
            var request = CreateRequest("UserNameIsGreaterThanAllowed", "password");
            var mediator = BuildMediator();

            //Act
            var response = await mediator.Send(request);

            //Assert
            //...assert the expected values of response.
        }
        catch (System.Exception ex)
        {

            throw;
        }
    }
}

以上是根据 MediatR.Examples.Autofac

提供的示例建模的