【问题标题】:Moq test on inherited class always returns null继承类的 Moq 测试总是返回 null
【发布时间】:2019-11-19 02:42:05
【问题描述】:

我在为实现存储库模式的控制器设置单元测试时遇到问题。我想检查控制器的返回值。在为存储库设置我的 Mock 时,继承的 IRepository 方法总是返回 null。我期待看到.ReturnsAsync("test")中定义的字符串“test”

存储库

public interface IRepository
{
    Task<T> Get<T>(string storedProcedure, object template);

    Task<T> Get<T>(string sql, CommandType commandType, object template);
}

public interface ITARRepository : IRepository
{
    // other methods 
    ...
}

控制器

private readonly ITARRepository Repository;

public async Task<IActionResult> GetTARTrackerResponse(long id)
{
    try
    {
        var result = await Repository.Get<string>("spName", new { @Params = id });

        return Ok(result);
    }
    catch (Exception e)
    {
        // logged
        ...

        return StatusCode((int)HttpStatusCode.InternalServerError);
    }
}

测试

[Fact]
public async Task Returns_OK_With_Tar_Tracker_Response()
{
    //arrange
    var mockRepo = new Mock<ITARRepository>();

    mockRepo
        .Setup(repo => repo.Get<string>("storedproc", new { test = 12345 }))
        .ReturnsAsync("test");

    var controller = new TARTrackerController(Logger, mockRepo.Object);

    //act
    var result = await controller.GetTARTrackerResponse(12345);
    var ObjectResult = result as ObjectResult;

    //assert
    Assert.IsType<OkObjectResult>(result);
    Assert.IsType<string>(ObjectResult.Value.GetType());
}

【问题讨论】:

  • 您能否检查您的代码并显示与控制器中的调用匹配的模拟设置?从帖子中显示的代码中您期望发生什么非常不清楚...
  • 设置中的参数匹配器与实际使用的不匹配,因此模拟不会按预期运行

标签: c# unit-testing inheritance moq xunit


【解决方案1】:

设置中的参数匹配器与被测主题中实际调用的内容不匹配,因此在执行测试时调用模拟不会按预期运行。

主题正在调用

var result = await Repository.Get<string>("spName", new { @Params = id });

虽然模拟的依赖项期望

.Setup(repo => repo.Get<string>("storedproc", new { test = 12345 }))

使用 It.IsAny&lt;T&gt;() 将模拟配置为与预期完全匹配或放松预期匹配

[Fact]
public async Task Returns_OK_With_Tar_Tracker_Response() {
    //arrange    
    string expected = "test";
    var mockRepo = new Mock<ITARRepository>();
    mockRepo
        .Setup(repo => repo.Get<string>(It.IsAny<string>(), It.IsAny<object>()))
        .ReturnsAsync(expected);

    var controller = new TARTrackerController(Logger, mockRepo.Object);

    //act
    var result = await controller.GetTARTrackerResponse(12345);    

    //assert
    OkObjectResult objectResult = Assert.IsType<OkObjectResult>(result);
    string actual = Assert.IsType<string>(objectResult.Value);
    Assert.Equal(expected, actual);
}

【讨论】:

  • 我是 Moq 的新手,所以感谢您的帮助。想知道“放松”匹配的参数是否是推荐的做法。
  • @dbarth 在这种情况下很难匹配匿名对象,因此这里建议使用放松匹配的方法。
  • @dbarth 在其他情况下可以轻松匹配参数然后进行显式匹配。
猜你喜欢
  • 2019-05-27
  • 2021-05-03
  • 1970-01-01
  • 2011-09-27
  • 1970-01-01
  • 1970-01-01
  • 2020-07-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多