Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用XUnit Mediatr和IServiceCollection的依赖项注入_C#_Dependency Injection_Xunit_Mediatr_Servicecollection - Fatal编程技术网

C# 使用XUnit Mediatr和IServiceCollection的依赖项注入

C# 使用XUnit Mediatr和IServiceCollection的依赖项注入,c#,dependency-injection,xunit,mediatr,servicecollection,C#,Dependency Injection,Xunit,Mediatr,Servicecollection,目前,我能够通过以下方式处理IServiceCollection,为特定服务注入mock public class TestClass { private IMediator _mediatr; private void SetupProvider(IUnitOfWork unitOfWork, ILogger logger) { configuration = new ConfigurationBuilder().Build(); _s

目前,我能够通过以下方式处理IServiceCollection,为特定服务注入mock

public class TestClass
{
    private IMediator _mediatr;

    private void SetupProvider(IUnitOfWork unitOfWork, ILogger logger)
    {
        configuration = new ConfigurationBuilder().Build();
        _services = new ServiceCollection();
        _services.AddSingleton(configuration);
        _services.AddScoped(x => unitOfWork);
        _services.AddSingleton(logger);
        _services.AddMediatR(Assembly.Load("Application"));
        _services.AddScoped(typeof(IPipelineBehavior<,>), typeof(LoggerBehaviour<,>));
        _mediator = _services.BuildServiceProvider().GetService<IMediator>();
    }

    [Fact]
    public async void UnitTest_Success()
    {
        var unitOfWork = new Mock<IUnitOfWork>();
        var logger = new Mock<ILogger>();
        SetupProvider(unitOfWork.Object, logger.Object);
        var fixture = new Fixture();
        var command = fixture.Create<MediatorCommand>();

        unitOfWork.Setup(x => x.Repository.FindAll(It.IsAny<IList<long>>(), It.IsAny<bool?>()))
        .ReturnsAsync(new List<Domain.Model>());

        var response = await _mediatr.Send(command);

        using (new AssertionScope())
        {
            response.Should().NotBeNull();
            response.IsSuccess.Should().BeTrue();
        }
    }
}
公共类TestClass
{
私人媒体;
专用void设置提供程序(IUnitOfWork、ILogger记录器)
{
配置=新建ConfigurationBuilder().Build();
_服务=新服务集合();
_services.AddSingleton(配置);
_AddScoped(x=>unitOfWork);
_服务。AddSingleton(记录器);
_services.AddMediatR(Assembly.Load(“应用”));
_addScope(typeof(IPipelineBehavior),typeof(loggerbehavior));
_中介=_services.BuildServiceProvider().GetService();
}
[事实]
公共异步void UnitTest_Success()
{
var unitOfWork=new Mock();
var logger=newmock();
SetupProvider(unitOfWork.Object、logger.Object);
var fixture=新fixture();
var命令=fixture.Create();
unitOfWork.Setup(x=>x.Repository.FindAll(It.IsAny(),It.IsAny())
.ReturnsAsync(新列表());
var response=wait_mediatr.Send(命令);
使用(新断言范围())
{
response.Should().NotBeNull();
response.issucess.Should().BeTrue();
}
}
}
对于以下受试对象:

public class MediatorCommand : IRequest<CommandResponse>
{
    public string Name { get; set ;}
    public string Address { get; set; }
}

public class MediatorCommandHandler : IRequestHandler<MediatorCommand, CommandResponse>
{
    private readonly ILogger _logger;
    private readonly IUnitOfWork _unitOfWork;

    public MediatorCommandHandler(IUnitOfWork unitOfWork, ILogger logger)
    {
        _logger = logger;
        _unitOfWork = unitOfWork;
    }

    public async Task<CommandResponse> Handle(MediatorCommand command, CancellationToken cancellationToken)
    {
        var result = new CommandResponse { IsSuccess = false };
        try
        {
            var entity = GetEntityFromCommand(command);
            await _unitOfWork.Save(entity);
            result.IsSuccess = true;
        }
        catch(Exception ex)
        {
            _logger.LogError(ex, ex.Message);
        }

        return result;
    }
}
公共类中介命令:IRequest
{
公共字符串名称{get;set;}
公共字符串地址{get;set;}
}
公共类MediatorCommandHandler:IRequestHandler
{
专用只读ILogger\u记录器;
私人只读i工作单元(unitof工作单元);;
公共中介CommandHandler(IUnitOfWork、ILogger记录器)
{
_记录器=记录器;
_unitOfWork=unitOfWork;
}
公共异步任务句柄(MediatorCommand命令、CancellationToken CancellationToken)
{
var result=newcommandresponse{issucess=false};
尝试
{
var entity=GetEntityFromCommand(命令);
等待_unitOfWork.Save(实体);
result.issucess=true;
}
捕获(例外情况除外)
{
_logger.LogError(例如,例如消息);
}
返回结果;
}
}
此测试运行良好,命令处理程序中使用unitOfWork和logger模拟

我尝试移动它,以便IServiceCollection构造在每个类中进行,而不是在每个测试中使用以下内容:

public class SetupFixture : IDisposable
{
    public IServiceCollection _services;
    public IMediator Mediator { get; private set; }
    public Mock<IUnitOfWork> UnitOfWork { get; private set; }

    public SetupFixtureBase()
    {
        UnitOfWork = new Mock<IUnitOfWork>();
        configuration = new ConfigurationBuilder().Build();
        _services = new ServiceCollection();
        _services.AddSingleton(configuration);
        _services.AddScoped(x => UnitOfWork);
        _services.AddSingleton(new Mock<ILogger>().Object);
        _services.AddMediatR(Assembly.Load("Application"));
        _services.AddScoped(typeof(IPipelineBehavior<,>), typeof(LoggerBehaviour<,>));
        Mediator = _services.BuildServiceProvider().GetService<IMediator>();
    }

    public void Dispose()
    {
        Mediator = null;
        _services.Clear();
        _services = null;
    }
}

public class TestClass : IClassFixture<SetupFixture>
{
    protected readonly SetupFixture _setupFixture;

    public UnitTestBase(SetupFixture setupFixture)
    {
        _setupFixture = setupFixture;
    }

    [Fact]
    public async void UnitTest_Success()
    {
        var fixture = new Fixture();
        var command = fixture.Create<MediatorCommand>();

        _setupFixture.UnitOfWork.Setup(x => x.Repository.FindAll(It.IsAny<IList<long>>(), It.IsAny<bool?>()))
        .ReturnsAsync(new List<Domain.Model>());

        var response = await _mediatr.Send(command);

        using (new AssertionScope())
        {
            response.Should().NotBeNull();
            response.IsSuccess.Should().BeTrue();
        }
    }
}
公共类SetupFixture:IDisposable
{
公共信息收集服务;
公共IMediator中介{get;private set;}
公共模拟工作单元{get;private set;}
公共SetupFixtureBase()
{
UnitOfWork=new Mock();
配置=新建ConfigurationBuilder().Build();
_服务=新服务集合();
_services.AddSingleton(配置);
_AddScoped(x=>UnitOfWork);
_services.AddSingleton(新的Mock().Object);
_services.AddMediatR(Assembly.Load(“应用”));
_addScope(typeof(IPipelineBehavior),typeof(loggerbehavior));
中介=_services.BuildServiceProvider().GetService();
}
公共空间处置()
{
调解人=null;
_服务。清除();
_服务=空;
}
}
公共类TestClass:IClassFixture
{
受保护的只读SetupFixture\u SetupFixture;
公共单元测试库(SetupFixture SetupFixture)
{
_setupFixture=setupFixture;
}
[事实]
公共异步void UnitTest_Success()
{
var fixture=新fixture();
var命令=fixture.Create();
_setupFixture.UnitOfWork.Setup(x=>x.Repository.FindAll(It.IsAny(),It.IsAny())
.ReturnsAsync(新列表());
var response=wait_mediatr.Send(命令);
使用(新断言范围())
{
response.Should().NotBeNull();
response.issucess.Should().BeTrue();
}
}
}
不幸的是,使用这种方法,我的mock不会被注入到命令处理程序中。有没有办法让它发挥作用


谢谢,

我发现了这个问题,它与转到IClassFixuture无关。问题是我在初始化基类上的中介,然后在派生类上添加模拟UnitOfWork

这会导致中介初始化失败,因为其中一个Beheviour期望的UnitOfWork当时还不在容器上

在添加了所有服务之后移动中介的初始化帮助我解决了这个问题,现在所有的工作都如预期的那样

如果您尝试相同的方法,请确保在初始化任何需要这些依赖关系的对象之前,将所有服务都包含在容器中


谢谢所有有意见的人。

你说的每节课是什么意思?你能再详细说明一下吗?我已经用我想用的代码修改了这个问题。我想在测试类的实例化上构建一次_服务,而不是每次运行测试。假定代码是简化的,但不完整,因此不清楚。显示已使用但未分配的变量。例如,在这两个测试示例中,
\u mediatr
在哪里分配了值。我是否能够按原样处理这段代码并重现问题?我已经更新了代码,以显示Mediator是如何实例化的