使用Unity IoC进行MVC集成测试 [英] MVC Integration tests with Unity IoC

查看:81
本文介绍了使用Unity IoC进行MVC集成测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用基于构造函数的DI后,尝试使用 Unity IoC. 问题是试图使集成测试正常工作.

Am trying Unity IoC, after using constructor based DI. Problem is trying to get integration tests working.

http://patrick.lioi.net/2013/06/20/streamlined-integration-tests/

运行集成测试应在合理的可能范围内使用尽可能多的真实系统"

"Running your integration tests should exercise as much of the real system as is reasonably possible"

上面的帕特里克(Patrick)描述了在MVC单元测试项目中设置IoC的方法.但是我对实现方法一窍不通

Patrick above describes setting up an IoC inside the MVC Unit test project.. but I'm stuck as to how to implement

public class HomeController : Controller
{
    readonly IWinterDb db;

    // Unity knows that if IWinterDb interface is asked for, it will inject in a new WinterDb()
    public HomeController(IWinterDb db)
    {
        this.db = db;
    }

    public ActionResult Index()
    {
        var stories = db.Query<Story>()
                        .OrderByDescending(s => s.Rating)
                        .Include(s => s.StoryType);

        return View(stories);
    }

单元测试很好,传递一个假的:

Unit tests are fine, passing in a fake:

[TestMethod]
public void Index_GivenFake_ShouldReturn100Stories()
{
    var db = new FakeWinterDb();
    db.AddSet(TestData.Stories);
    var controller = new HomeController(db);

    var result = controller.Index() as ViewResult;
    var model = result.Model as IEnumerable<Story>;

    Assert.AreEqual(100, model.Count());
}

但是我喜欢用于测试整个堆栈的集成测试:

However I like integration tests which test the whole stack:

//Integration tests depend on the test data inserted in migrations
[TestClass]
public class HomeControllerTestsIntegration
{
    [TestMethod]
    public void Index_GivenNothing_ResultShouldNotBeNull()
    {
        var controller = new HomeController();

        var result = controller.Index() as ViewResult;

        Assert.IsNotNull(result);
    }

问题:这不会编译(因为没有无参数的构造函数).而且没有调用Unity为HomeController注入正确的依赖项.

Problem: This will not compile (as no parameterless constructor). And Unity is not being called to inject in the correct dependency for HomeController.

团结起来:

public static class UnityConfig
{
    public static void RegisterComponents()
    {
        var container = new UnityContainer();

        // register all your components with the container here
        // it is NOT necessary to register your controllers

        container.RegisterType<IWinterDb, WinterDb>();

        // for authentication
        container.RegisterType<AccountController>(new InjectionConstructor());

        DependencyResolver.SetResolver(new UnityDependencyResolver(container));
    }
}

[TestMethod]
public void Index_GivenNothing_ResultShouldNotBeNull()
{
    UnityConfig.RegisterComponents(); 
    var controller = UnityConfig.container.Resolve<HomeController>();

    var result = controller.Index() as ViewResult;

    Assert.IsNotNull(result);
}

确保单身人士在那里.

public static class UnityConfig
{
    public static UnityContainer container;

    public static void RegisterComponents()
    {
        container = new UnityContainer();

        // register all your components with the container here
        // it is NOT necessary to register your controllers

        //container.RegisterType<IWinterDb, WinterDb>();

        container.RegisterTypes(
            AllClasses.FromLoadedAssemblies(),
            WithMappings.FromMatchingInterface, // Convention of an I in front of interface name
            WithName.Default
            );  // Default not a singleton in Unity

        // for authentication
        container.RegisterType<AccountController>(new InjectionConstructor());

        DependencyResolver.SetResolver(new UnityDependencyResolver(container));
    }
}

将Unity暴露给测试项目

Exposing Unity to the test project

推荐答案

您需要通过容器来解析控制器,以便Unity为您解决依赖关系.

You need to resolve your controller via the container for Unity to resolve dependencies for you.

它可能就像替换它一样简单:

It may be as simple as replacing this:

var controller = new HomeController();

与此:

var controller = container.Resolve<HomeController>();

您显然需要将您的容器暴露给测试类.连接生产代码时通常不会这样做.

You will obviously need to expose your container to your test class. This is something you would not normally do when wiring up your production code.

这篇关于使用Unity IoC进行MVC集成测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆