使用Unity IoC进行MVC集成测试

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

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

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

上面的Patrick描述了在MVCunit testing项目中设置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() .OrderByDescending(s => s.Rating) .Include(s => s.StoryType); return View(stories); } 

unit testing很好,传入假的:

 [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; 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注入正确的依赖项。

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(); // for authentication container.RegisterType(new InjectionConstructor()); DependencyResolver.SetResolver(new UnityDependencyResolver(container)); } } 

EDIT1:

 [TestMethod] public void Index_GivenNothing_ResultShouldNotBeNull() { UnityConfig.RegisterComponents(); var controller = UnityConfig.container.Resolve(); 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(); 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(new InjectionConstructor()); DependencyResolver.SetResolver(new UnityDependencyResolver(container)); } } 

将Unity公开给测试项目

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

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

 var controller = new HomeController(); 

有了这个:

 var controller = container.Resolve(); 

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