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

标签 c# unit-testing integration-testing mediatr .net-4.7

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

编辑后请阅读

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

我的类(class)是这样的:

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

我没有使用 Meditr async,我使用的是 .net framework 4.7 而不是 asp.net core,所以,一切看起来都返回了我对 asp.net core 的答案。

当我构造 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 来注入(inject)处理程序,因此,我所做的任何请求总是由正确的方法处理。 我所要做的就是像这样调用:

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。这里的这个类在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 提供的示例建模的

关于c# - 如何在 .net framework 4.7 上使用 Mediatr 进行集成测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57443102/

相关文章:

java - 如何使 WireMock 验证提供更多信息?

unit-testing - Grails 2.x中的Grails单元测试失败

django - 集成测试DRF

email - 是否有用于测试 "throwaway"电子邮件的标准域?

c# - .Net 的 DateTime 方法是否能够识别闰秒?

c# - 在 Visual Studio 2010 中为 Sharepoint 2010 合并工作流启动信息路径表单

c# - 安装 Xamarin IOS.Setup 和 Android.Setup 时 "' 1.0.0 ' is not a valid short file name"

c# - 允许选定子对象的 Unity 自定义检查器

java - 从单元测试中消除 null 的方法

angularjs - Protractor 找不到 chromedriver : The driver executable does not exist: