简体   繁体   English

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

[英]How to mock the dependency injection object in unit test

My project requires unit testing.我的项目需要单元测试。 I am using constructor dependency injection in my controller.我在我的控制器中使用构造函数依赖注入。 When I mock the injected dependency object in my unit testing project and call it in a test method.当我在我的单元测试项目中模拟注入的依赖对象并在测试方法中调用它时。 Returns null in all cases.在所有情况下都返回 null。

Controller Class:控制器类:

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);
    }
}

My Repository Class我的存储库类

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;
    }
}

Now I need to test the GetAllTypes methods in my controller class.现在我需要在我的控制器类中测试 GetAllTypes 方法。 My Test Class is below mentioned:我的测试课程如下所述:

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());
    }
}

How can I do it?我该怎么做? Any one know the answer for this question.任何人都知道这个问题的答案。

As @Nkosi mentioned you have to use moq setup.正如@Nkosi 提到的,您必须使用最小起订量设置。 Define your mocks outside constructor and initalize them in test class's constructor.在构造函数之外定义你的模拟并在测试类的构造函数中初始化它们。

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());
    }
}

Also, why you inject your dbcontext to controller?your repository should depend dbcontext not controller.另外,为什么要将 dbcontext 注入控制器?您的存储库应该依赖 dbcontext 而不是控制器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM