【问题标题】:How to properly mock a controller that calls methods in different projects that implement dependency injection?如何正确模拟调用不同项目中实现依赖注入的方法的控制器?
【发布时间】:2020-01-16 08:24:45
【问题描述】:

我有一个这样的解决方案

>Solution
>>BusinessLogic.proj
>>DataAccessLayer.proj
>>Domain.proj
>>Web.proj
>>Test.proj

Web.UserController

public class UserController
{
    private readonly IUserManager _userManager;

    public UserController(IUserManager userManager)
    {
        _userManager = userManager;
    }

    public string GetUser()
    {
        return _userManager.GetAllUsers();
    }
}

BusinessLogic.UserManager

public class UserManager : IUserManager
{
    private readonly IUserQueryMaster _userQueryMaster;

    public UserManager(IUserQueryMaster userQueryMaster)
    {
        _userQueryMaster = userQueryMaster;
    }
    public string GetAllUsers()
    {

        return _userQueryMaster.GetAllUsers();
    }
}

DataAccesLayer.UserQueryMaster

public class UserQueryMaster : IUserQueryMaster
{
    private readonly CoreContext _CoreContext;

    public UserQueryMaster(CoreContext CoreContext)
    {
        _CoreContext = CoreContext;
    }

    public string GetAllUsers()
    {
        var res = _CoreContext.Users.ToList();
        var json = JsonConvert.SerializeObject(res, Formatting.Indented);
        return json;
    }
}

测试

public class UnitTest
{
    [Fact]
    public void GetAllUsers()
    {
        //Arrange
        string JsonResult = @"{"//user1, user2... json format 
                                }";

        var mockIUserManager = new Mock<IUserManager>();
        UserController GetUserController = new UserController(mockIUserManager.Object);


        //Act
        var result = GetUserController.GetUser();

        //Assert
        Assert.Equal(JsonResult, result);
    }

}

现在,当我调试单元测试时,执行无法进入 (F11) 类“UserManager”,导致“结果”评估为“空”。我怀疑这可能是因为我没有在测试中的任何地方指定 UserManager 和 UserQueryMaster 都有自己需要的服务来访问我正在寻找的数据。

我的问题是,如何使用这种“嵌套依赖注入”创建单元测试?

【问题讨论】:

  • 你在嘲笑IUserManager,这意味着所有的嵌套服务都不相关。你唯一缺少的是设置你的模拟来返回你可以测试的东西。例如:mockIUserManager.Setup(mum =&gt; mum.GetAllUsers()).Returns(JsonResult);
  • 你没有嘲笑IUserManager的任何方法...

标签: c# dependency-injection .net-core moq xunit


【解决方案1】:

你在嘲笑IUserManager,这意味着所有的嵌套服务都不相关。

您唯一缺少的是设置您的模拟以返回您可以测试的内容。例如:

mockIUserManager.Setup(mum => mum.GetAllUsers()).Returns(JsonResult);

【讨论】:

  • 感谢您的回复@DavidG。如果我理解正确,以这种方式设置模拟就像是在告诉:'好的,每当我的测试使用这个名为 GetAllUsers() 的方法时,都应该返回字符串'JsonResult'。如果从不在测试环境之外调用实际方法 GetAllUsers() 为什么这会很有价值?稍后在测试中,我将编写如下代码:var result = GetUserController.GetUser();Assert.Equal(JsonResult, result);,如果我将 JsonResult 和结果设置为 = 'asd',则相同。我的测试会通过,但毫无价值,因为从未进入“真正的实施”
  • 单元测试的重点是只测试这个代码单元。您应该有另一个测试来测试GetAllUsers 方法的实现。对于这个单元测试,您只对控制器操作感兴趣。
猜你喜欢
  • 2013-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-08
  • 2016-09-15
  • 2021-05-21
  • 2023-03-20
  • 2020-06-06
相关资源
最近更新 更多