Let's see an example using ASP.NET MVC 3, Ninject as IoC container, Moq as mocking framework and NBuilder as data builder framework:

Giving this Model:
public interface IProductRepository
{
   IEnumerable<Product> GetAll();
   Product GetOne(int productId);
   void InsertOrUpdate(Product product);
   void Save();
}

public class ProductRepository : IProductRepository
{
   private readonly Sample1WebContext context;

   [Inject]
   public ProductRepository(Sample1WebContext context)
   {
      this.context = context;
   }

   public IEnumerable<Product> GetAll()
   {
      IQueryable<Product> query = context.Products;
      return query.ToList();
   }

   public IEnumerable<Product> GetOne(int productId)
   {
      return context.Products.FirstOrDefault(p => p.ProductId == productId);
   }

   public void InsertOrUpdate(Product product)
   {
      if (product.ProductId == 0)
      {
         // New entity
         context.Products.Add(product);
      }
      else
      {
         // Existing entity
         context.Products.Attach(product);
         context.Entry(product).State = EntityState.Modified;
      }
   }

   public void Save()
   {
      context.SaveChanges();
   }
}

public class Product
{
   public int ProductId { get; set; }
   public string Name { get; set; }
   public string Description { get; set; }
}
And this Controller:
public class ProductController : Controller
{
   private readonly IProductRepository productRepository;

   [Inject]
   public ProductController(IProductRepository productRepository)
   {
      this.productRepository = productRepository;
   }

   public ViewResult Index()
   {
      IEnumerable<Product> products = this.productRepository.GetAll();

      return View(products);
   }

   public ActionResult Create()
   {
      return View(new Product());
   }

   [HttpPost]
   public ActionResult Create(Product product)
   {
      if (ModeState.IsValid)
      {
         this.productRepository.InsertOrUpdate(product);
         this.productRepository.Save();

         return RedirectToAction("Index");
      }

      return View(product);
   }
}
We can write this (very simple) test to the "Index" action of the ProductController, using MSTest, Moq, NBuilder and Ninject :
[TestClass()]
public class ProductsControllerTest
{
   private IKernel kernel = new StandardKernel();

   [TestMethod()]
   public void Index_Returns_List_Of_Products_Without_IslandUnit()
   {
      // Arrange
      // Create the mock object using Moq
      Mock<IProductRepository> productRepositoryMock = new Mock<IProductRepository>();

      // Produce data with NBuilder that will be returned by mock object
      IEnumerable<Product> productsList = Builder<Product>().CreateListOfSize(10).Build();

      // Setup the method of mock object used by SUT, to return something
      // the data produced by NBuilder. In fact, we are creating an STUB.
      productRepositoryMock.Setup(m => m.GetAllProducts()).Returns(productsList);

      // Inform to IoC container: When someone needs an IProductRepository, provides
      // the mocked object that we already setted up
      kernel.Bind<IProductRepository>().ToMethod(m => productRepositoryMock.Object);

      // Act
      ProductsController sut = kernel.Get<ProductsController>();
      ViewResult viewResult = sut.Index();

      // Assert
      IEnumerable<Product> viewData = viewResult.ViewData.Model as IEnumerable<Product>;
      Assert.IsNotNull(viewData);
      Assert.AreEqual(10, viewData.Count());
   }
}
Nice! But a little verbose.
With IslandUnit, we could write the same test, also using MSTest, Moq, NBuilder and Ninject :
[TestClass()]
public class ProductsControllerTest
{
   [TestMethod()]
   public void Index_Returns_List_Of_Products_Using_IslandUnit()
   {
      // Arrange
      // Here's the "magic"
      Isolator isolator = new Isolator();
      isolator.AddDependency<IProductRepository>().WithStubFor(m => m.GetAllProducts()).ReturningWith(10);

      // Act
      ProductsController sut = isolator.CreateSut<ProductsController>();
      ViewResult viewResult = sut.Index();

      // Assert
      IEnumerable<Product> viewData = viewResult.ViewData.Model as IEnumerable<Product>;
      Assert.IsNotNull(viewData);
      Assert.AreEqual(10, viewData.Count());
   }
}
Great! Clean, concise, fluent, intuitive!

And if you decide, for example, to use another Ioc container, you don't need to change the code in your tests. Wow!

But there's more! Check our samples with other complete examples.

Last edited Mar 18, 2011 at 11:46 PM by andborges, version 13

Comments

No comments yet.