简体   繁体   English

使用 Ninject 注入依赖项而不使用构造函数注入 - 单元测试

[英]Inject Dependency without using Constructor injection using Ninject - Unit Tests

I am creating Unit Tests for existing .NET Framework 4.5 API project.我正在为现有的 .NET Framework 4.5 API 项目创建单元测试。 The existing project has parameterless constructor by design and dependency injection was implemented as per the class below using Ninject.现有项目通过设计具有无参数构造函数,并且依赖注入是按照下面的 class 使用 Ninject 实现的。

I would like to Mock the interface and create an instance of the class for testing as shown below but the constructor is parameterless.我想模拟接口并创建一个 class 的实例进行测试,如下所示,但构造函数是无参数的。 I can't figure out how to inject my Mock member.Object.我不知道如何注入我的 Mock member.Object。 The main goal is I don't want to change the design of existing classes unless there is no other way.主要目标是我不想改变现有类的设计,除非没有其他办法。

public class MemberController : ApiController
{
    StandardKernel DependencyKernel;
    private IMember member;
    
    public MemberController()
    {
        DependencyKernel = new StandardKernel();
        DependencyKernel.Load(Assembly.GetExecutingAssembly());
        member = DependencyKernel.Get<IMember>();
    }

    [HttpPost]
    public HttpResponseMessage AddMember(MemberRequest model)
    {
        try
        {
            int memberRecords;
            
            member.SaveMember(model, out memberRecords);

            if (memberRecords > 0)
                return new HttpResponseMessage { StatusCode = HttpStatusCode.Conflict, Content = new StringContent("Member with same reference exists") };
            else
                return new HttpResponseMessage { StatusCode = HttpStatusCode.OK, Content = new StringContent("Member added successfully") };
        }
        catch (Exception ex)
        {
            return new HttpResponseMessage { StatusCode = HttpStatusCode.InternalServerError, Content = new StringContent(ex.Message) };
        }
    }
}

//Test Class //测试Class

public class MemberControllerTests
{
    StandardKernel DependencyKernel;
    private MemberController memberController;
    Mock<IMember> member = new Mock<IMember>();

    public MemberControllerTests()
    {
        DependencyKernel = new StandardKernel();
        DependencyKernel.Load(Assembly.GetExecutingAssembly());
    }

    [SetUp]
    public void Setup()
    {
        
    }

    [Test]
    public void should_AddMember()
    {
        //Arrange
        MemberRequest member = new MemberRequest{ };
        int memberRecords;

        member.Setup(x => x.SaveMember(member, out memberRecords));

        memberController = new MemberController(member.Object); //This will obviously not work, the MemberController has parameterless constructor
        //Act
        var result = MemberController.AddMember(member);
        //Assert
        Assert.AreEqual(result.StatusCode, HttpStatusCode.OK);
    }
}

This post has the answer to the question. 这篇文章有这个问题的答案。 If IMember member property is made public in MemberController, I can new up the MemberController class and set the value of its member property to the MOCK.如果 IMember 成员属性在 MemberController 中公开,我可以新建 MemberController class 并将其成员属性的值设置为 MOCK。

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

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