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

3

我的项目需要进行单元测试。我在控制器中使用构造函数依赖注入。当我在我的单元测试项目中模拟注入的依赖对象并在测试方法中调用它时,无论什么情况下都会返回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());
    }
}

我该怎么做?有人知道这个问题的答案吗?


2
模拟仓库未设置任何操作,因此默认情况下将返回 null。 - Nkosi
参考 Moq 快速入门 以更好地了解如何使用 MOQ。 - Nkosi
如果答案解决了您的问题,您可以将其标记为答案。 - Barış Can Yılmaz
1个回答

7

正如@Nkosi所提到的,您需要使用moq setup。将您的模拟定义在构造函数外部,并在测试类的构造函数中初始化它们。

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而不是控制器。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接