在.NET CORE3.1中的基本控制器中使用受保护中介的单元测试派生的控制器类

在.NET CORE3.1中的基本控制器中使用受保护中介的单元测试派生的控制器类,.net,core,xunit,.net,Core,Xunit,我在模拟中介中面临问题,该中介在基类控制器中定义为受保护的属性。 我想测试派生类控制器的方法,它使用基类属性。 查找代码详细信息以供参考: [ApiController] public class BaseController : ControllerBase { private IMediator _mediator; private IUrlHelper _urlHelper; protected virtual IMediator Mediator => _

我在模拟中介中面临问题,该中介在基类控制器中定义为受保护的属性。 我想测试派生类控制器的方法,它使用基类属性。 查找代码详细信息以供参考:

[ApiController]
public class BaseController : ControllerBase
{
    private IMediator _mediator;
    private IUrlHelper _urlHelper;

    protected virtual IMediator Mediator => _mediator ?? (_mediator = HttpContext.RequestServices.GetService<IMediator>());
    public BaseController()
    {

    }
}

[Route("api/[controller]")]
[ApiController]

public class ArchiveFileController : BaseController
{
    public ArchiveFileController()
    {
    }
    [HttpPost]
    public async Task<ActionResult> Post([FromBody]UploadArchiveCommand model)
    {
        try
        {
            var response = await Mediator.Send(new UploadArchiveCommand(model));
            return CreatedAtAction("Get", new { id = response.Id }, response);
        }
        catch (Exception ex)
        {
            return BadRequest(ex.Message);
        }
    }

 }
[ApiController]
公共类BaseController:ControllerBase
{
私人中介人;
私人IUrlHelper _urlHelper;
受保护的虚拟IMediator Mediator=>\u Mediator???(\u Mediator=HttpContext.RequestServices.GetService());
公共BaseController()
{
}
}
[路由(“api/[控制器]”)]
[ApiController]
公共类ArchiveFileController:BaseController
{
公共ArchiveFileController()
{
}
[HttpPost]
此处的公共异步任务Mediator为空。

有几件事:

  • 不要只为公共依赖项创建基类。这里的基类不会增加任何值
  • 对依赖项使用依赖项注入,而不是服务位置

删除基类,只需通过其构造函数将依赖项注入控制器类中。然后,您就可以在单元测试中模拟这些依赖项。

您是否配置了
HttpContext
?为什么不将mediator作为参数传递给基类构造函数?我们不能以这种方式实现吗?@ChandanSingh hi将其更改为构造函数注入,或者您发现aroundI使用构造函数注入的其他方式。有没有一种方法可以使用相同的基类实现进行测试
     [Fact]
    public async Task PostArchiveFileTest_Returns_CreatedArchiveFileInformation()
    {
        // Arrange
        var mockUploadArchiveCommand = fixture.Create<UploadArchiveCommand>();

        //Action
        _mediatorMock.Setup(x => x.Send(It.IsAny<UploadArchiveCommand>(), new CancellationToken())).
         ReturnsAsync(new UploadArchiveViewModel { Identifier = mockUploadArchiveCommand.Identifier, FileName = mockUploadArchiveCommand.FileName });

        var _archiveFileController = new ArchiveFileController();

        var result = await _archiveFileController.Post(mockUploadArchiveCommand);

        var archiveFileInfo = ((CreatedAtActionResult)result).Value as UploadArchiveViewModel;

        // Assert
        Assert.Equal(archiveFileInfo.Identifier, mockUploadArchiveCommand.Identifier);
    }