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 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);
}
Problem: This will not compile (as no parameterless constructor). And Unity is not being called to inject in the correct dependency for HomeController.
Unity wire up:
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));
}
}
Edit1:
[TestMethod]
public void Index_GivenNothing_ResultShouldNotBeNull()
{
UnityConfig.RegisterComponents();
var controller = UnityConfig.container.Resolve<HomeController>();
var result = controller.Index() as ViewResult;
Assert.IsNotNull(result);
}
Making sure the singleton is there.
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));
}
}
Exposing Unity to the test project