【问题标题】:.Net Core integration tests with mock keeps returning null.Net Core 与 mock 的集成测试不断返回 null
【发布时间】:2021-01-23 13:53:14
【问题描述】:

我正在努力成为一个好孩子并编写一些单元和集成测试,但我正在慢慢放弃。在控制器方面,我有:

public class PointController : BaseApiController
{
    private readonly IPointL _pointL;

    public PointController(IMapper mapper, IPrincipal principal, IPointL pointL) : base(mapper, principal)
    {
        _pointL = pointL;
    }

    // GET: api/<PointController>
    /// <summary>
    /// Get point by id.
    /// </summary>
    /// <param name="id">Point id.</param>
    /// <returns></returns>
    [HttpGet("{id}")]
    public async Task<PointDTO> GetPointAsync(int id)
    {
        // Get point.
        var pointModel = await _pointL.GetPointAsync(id);
        var pointDTO = _mapper.Map<PointDTO>(pointModel);

        return pointDTO;
    }
} 

所以var pointModel = await _pointL.GetPointAsync(id);这一行实际上调用了我的逻辑层:

public class PointL : BaseL, IPointL
{
    private readonly IBaseDAL _baseDAL;

    public PointL(IMapper mapper, IPrincipal principal, IBaseDAL baseDAL) : base(mapper, principal)
    {
        _baseDAL = baseDAL;
    }

    ///<inheritdoc/>
    public async Task<PointModel> GetPointAsync(int id)
    {
        _logger.Info($"Get point with id {id}.");

        var pointDBModel = await _baseDAL.GetPointAsync(id);
        if (pointDBModel is null)
        {
            throw new Exception($"Point with id {id} not found.");
        }

        var pointModel = _mapper.Map<PointModel>(pointDBModel);

        return pointModel;
    }
}

使用await _baseDAL.GetPointAsync(id); 下降到最后的 DAL 层

public partial class BaseDAL
{
    ///<inheritdoc/>
    public async Task<Point> GetPointAsync(int id)
    {
        _logger.Info($"Get point from database with id {id}.");

        using var dbGlistaContext = new GlistaContext(_options);
        var point = await dbGlistaContext.Point.FindAsync(id);

        return point;
    }
}

现在我的计划是为控制器上的GetPointAsync(int id) 方法编写一个集成测试。我想,这是通常的方式还是我弄错了? 无论哪种方式,这都是我不工作的尝试:

private readonly PointController _sut;
private readonly Mock<IPointL> _pointLMock = new Mock<IPointL>();
protected readonly Mock<IMapper> _mapperMock = new Mock<IMapper>();
protected readonly Mock<IPrincipal> _principalMock = new Mock<IPrincipal>();

public PointControllerTests()
{
    _sut = new PointController(_mapperMock.Object, _principalMock.Object, _pointLMock.Object);
}

[Fact]
public async System.Threading.Tasks.Task GetPointAsync_ShouldReturnPoint_WhenPointExists()
{
    // Arrange.
    var pointId = 1;
    var pointModel = new PointModel
    {
        Id = pointId,
        Name = "T01",
    };
    _pointLMock.Setup(x => x.GetPointAsync(pointId))
        .ReturnsAsync(pointModel);

    // Act.
    var point = await _sut.GetPointAsync(pointId); // Keeps returning null no matter what! :(

    // Assert.
    Assert.Equal(pointId, point.Id);
}

这是由于某种原因不能作为模拟不断返回空值!有人知道为什么吗?我看过一些教程,但我无法弄清楚解决方案。

编辑:

我发现控制器

        var pointModel = await _pointL.GetPointAsync(id);
        var pointDTO = _mapper.Map<PointDTO>(pointModel);

获取pointModel,但是,到 DTO 的映射返回 null。因此我尝试设置映射器模拟

var pointDTO = new PointDTO();
mapperMock.Setup(m => m.Map<PointModel, PointDTO>(It.IsAny<PointModel>())).Returns(pointDTO);

但是,没有任何成功。

【问题讨论】:

    标签: asp.net-core integration-testing


    【解决方案1】:

    您需要设置映射器模拟对象的Map 方法。

    _mapperMock.Setup(x => x.Map<PointDTO>(It.IsAny<PointDTO>()))
        .Returns(...);
    

    【讨论】:

    • 我试过_mapperMock.Setup(m =&gt; m.Map&lt;PointModel, PointDTO&gt;(It.IsAny&lt;PointModel&gt;())).Returns(pointDTO);,但它仍然映射到null
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-02
    • 2020-12-16
    • 1970-01-01
    • 2020-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多