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

时间:2021-07-06 18:07:58

标签: c# unit-testing mocking moq

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

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

1 个答案:

答案 0 :(得分:2)

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