0

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

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();
        }
    }
}

对于以下测试对象

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

该测试运行良好,并且在命令处理程序中使用了 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();
        }
    }
}

不幸的是,使用这种方法,我的模拟不会被注入命令处理程序。有没有办法让它工作?

谢谢,

4

1 回答 1

0

我发现了这个问题,它与迁移到 IClassFixuture<> 无关。问题是我在基类上初始化 Mediator,然后在派生类上添加模拟 UnitOfWork。

这会导致 Mediator 初始化失败,因为其中一个行为期望 UnitOfWork 当时还没有在容器上。

添加所有服务后移动 Mediator 的初始化帮助我解决了问题,现在一切都按预期工作。

如果您尝试相同的操作,请确保在初始化任何需要这些依赖项的对象之前包含容器中的所有服务。

感谢所有提供意见的人。

于 2019-11-16T23:32:47.283 回答