c# - 使用 Unity IoC 进行 MVC 集成测试

标签 c# asp.net-mvc inversion-of-control unity-container integration-testing

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

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

“运行集成测试应该尽可能多地测试真实系统”

上面的 Patrick 描述了在 MVC 单元测试项目中设置 IoC.. 但我不知道如何实现

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

单元测试没问题,传入一个假的:

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

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

//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 注入(inject)正确的依赖项。

Unity 接线:

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

编辑1:

[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暴露给测试项目

最佳答案

您需要通过容器来解析您的 Controller ,以便 Unity 为您解析依赖关系。

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

var controller = new HomeController();

用这个:

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

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

关于c# - 使用 Unity IoC 进行 MVC 集成测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21263197/

相关文章:

c# - onkeyup 事件 asp.net

c# - 从 32 位程序启动 64 位版本的 regedit 以创建 sql 别名

asp.net-mvc - 从 Controller 获取基本 URL 的最佳方法是什么

dependency-injection - 将 Spring.Net IoC 替换为另一个容器(例如 Ninject)

.net - 使用具有自己抽象的 IoC 高级功能

c# - 在 switch 语句中使用字符串集合

c# - Visual Studio 中字符串的快捷方式

asp.net-mvc - 操作方法参数不为空,尽管它应该是

c# - 在 ASP.NET Core 中使用 WebGrid

c# - StructureMap 对象重新加载