使用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();
您显然需要将容器暴露给测试类。 这是您在连接生产代码时通常不会做的事情。