使用Ninject进行集成测试

5
我知道在单元测试中不应该使用依赖注入,以便可以独立测试每个层次。但是我仍然想为我的控制器创建集成测试。因此,我需要从单元测试将我的存储库注入到控制器中。
我采用通用的方法,使用 T4 脚本为每个控制器创建一个测试类,其中包含每个 ActionResult 的测试方法。这个测试方法应该简单地调用这个方法,以确保没有异常被抛出到表面上。
由于使用了这个 T4 脚本,我不能手动将存储库提供给控制器。我需要使用依赖注入。
基于以往的经验,这应该可以工作,但我一直收到错误提示:
Unable to get default constructor for class <<UnitTest>>

目前我的生成类看起来像这样:

[TestClass]
public class TestControllersHomeController
{
    private EL.NET.Web.Controllers.HomeController c;
    //setup
    public TestControllersHomeController(Project.Controllers.HomeController c)
    {
        this.c = c;
    }
    [ClassInitialize]
    public void ClassInitialize()
    {

        var kernel = NinjectWebCommon.CreatePublicKernel();
        kernel.Bind<TestControllersHomeController>().ToSelf();
        kernel.Bind<Project.Controllers.HomeController>().ToSelf();
    }
    [TestMethod]
    public void TestIndex()
    {
        var result = c.Index();
        Assert.IsNotNull(result);
    }

编辑:

我已经发现,可以通过IKernel的GetService()方法加载存储库。但对于会员提供者来说,这种方法不起作用。 再次说明,我不想模拟提供者,我想执行集成测试,以便知道我的控制器方法是否会引发任何异常。

1个回答

4

单元测试必须有一个默认构造函数:

[TestClass]
public class TestControllersHomeController
{
    private HomeController _sut;

    [TestInitialize]
    public void MyTestInitialize() 
    {
        var kernel = NinjectWebCommon.CreatePublicKernel();
        _sut = kernel.Resolve<HomeController>();
    }

    [TestMethod]
    public void TestIndex()
    {
        var result = _sut.Index();
        Assert.IsNotNull(result);
    }
}

非泛型方法 'Ninject.Syntax.IResolutionRoot.Resolve(Ninject.Activation.IRequest)' 无法与类型参数一起使用。 - ckonig
@ckonig 使用 Get<T> 扩展方法代替 Resolve。因此,kernel.Get<HomeController>(); 调用应该可以工作,并且不要忘记添加 using Ninject; - nemesv
在这种特定情况下起作用的是IKernel的GetService()方法。现在我正在努力解决自定义成员资格提供程序问题。 - ckonig
是的,我知道在测试中不应该进行依赖注入,但是当您必须在现有代码中实现它时,这个代码段确实很有帮助 :) - Tony

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