如何在单元测试中模拟依赖注入对象

问题描述 投票:0回答:1

我的项目需要单元测试。我在控制器中使用构造函数依赖注入。当我在单元测试项目中模拟注入的依赖项对象并在测试方法中调用它时。在所有情况下都返回 null。

控制器类:

public class Owner:Controller
{
    private readonly IComRepository repository;
    private readonly DbContext context;
    
    public Owner(IComRepository repository, DbContext context)
    {
      this.repository=repository;
      this.context=context;
    }

    [HttpGet("GetAllTypes")]
    public async Task<IActionResult> GetAllTypes()
    {
      var ownerTypes=repository.GetTypes();
        return Ok(ownerTypes);
    }
}

我的存储库类

public Interface IComRepository
{
    IList<Type> GetTypes();
}
        
public Class ComRepository : IComRepository
{
    private readonly DbContext context;
    public ComRepository(DbContext context)
    {
        this.context=context;
    }
    public IList<Type> GetTypes()
    {
        var allTypes= context.Types.ToList();
        return allTypes;
    }
}

现在我需要测试控制器类中的 GetAllTypes 方法。我的测试班如下:

using moq;
[TestClass]
public Class OwnerTest
{
    public OwnerTest()
    {
        var mockIcomrepo = new Mock<IComRepository>();
        var mockDbcontext = new Mock<Dbcontext>();
        OwnerController owner = new OwnerController(mockDbContext.Object, mockIcomrepo.Object);
    
    }
    [TestMethod]
    public void GetTypes()
    {
        var allTypes= owner.GetAllTypes(); //It's not trigger to my controller
        Assert.AreEqual(5,allTypes.count());
    }
}

我该怎么做?任何人都知道这个问题的答案。

c# unit-testing mocking moq
1个回答
7
投票

正如 @Nkosi 提到的,你必须使用起订量设置。在构造函数外部定义模拟并在测试类的构造函数中初始化它们。

using moq;
[TestClass]
public Class OwnerTest
{
    private readonly IComRepository _mockRepository;
    private readonly OwnerControler _ownerController;
    
    //your mock data
    private readonly IList<Type> _mockData; 

    public OwnerTest()
    {
        _mockRepository= new Mock<IComRepository>();

        _ownerController = new OwnerController(mockDbContext.Object, mockIcomrepo.Object);
        _mockData = new IList<Type>{"Data1","Data2","Data3","Data4","Data5"};

    }
    
    //choose better names for testing a method 
    //Naming convention like this MethodName_StateUnderTest_ExpectedResult;
    
    [TestMethod]
    public void GetAllTypes() 
    {
        _mockRepository.Setup(p=>p.GetAllTypes()).Returns(mockData);

        var result= _ownerController.GetAllTypes();
        var okResult=Assert.IsType<OkObjectResult>(result)
        var returnTypes=Assert.IsAssignableFrom<IList<Type>>(okResult.Value);
        Assert.AreEqual(5,returnTypes.count());
    }
}

另外,为什么你将 dbcontext 注入到控制器?你的存储库应该依赖于 dbcontext 而不是控制器。

© www.soinside.com 2019 - 2024. All rights reserved.