views:

175

answers:

3

I'm trying to get my head around using Nunit, Ninject, MVC2 and the ADO.Net Entity Data Model.

Let's say I have have a ProductsController instantiating a SqlProductsRepository class.

public class ProductsRepository : IProductsRepository
{
    public MyDbEntities _context;

    public ProductsRepository()
    {
        _context = new MyDbEntities();
    }

    public IList<Product> GetAllProducts()
    {
        return (from p in _context.Products select p).ToList();
    }
}

public class ProductsController : Controller
{
    public ActionResult ProductsList()
    {
        ProductsRepository r = new ProductsRepository();
        var products = r.GetAllProducts();

        return View(products);
    }
}

I'd like to be able to perform unit testing on ProductsRepository to ensure this is returning the correct data but i'm not sure how to write the Test Class.

Every tutorial/document I've read so far points me to creating a Mock object using IProductsRepository and then injecting and testing the Controller.

This seems, to me, to bypass the concrete implementation.

MyDbEntities comes from an ADO.Net Entity Data Model .edmx

+2  A: 

It sounds like you're wanting to create an integration test for ProductsRepository rather than a unit test, since you'd be testing against the database so that you can check it's giving you the right data.

It's when unit testing the Controller that you'd want to mock the ProductsRepository.

In my integration tests for ProductsRepository, I'd be doing the obvious things like

public void TestProductsRepository()
{
  var context = new MyDbEntities();

  // add a new product

  var products = context.GetAllProducts();

  // check products contains new product
}
Samuel Jack
I'd like to test more complex methods in the repository such as: GetProductByBrandNameAndProductTypeAndProductName(string brandName, string productTypeSysName, string productName)To ensure this is returning the correct data. I thought this might be a valid unit test
sf
That's definitely a valid thing to test, but I probably wouldn't describe it as a unit test because your repository is having to integrate with Entity Framework to get the result.
Samuel Jack
would you still use nunit for this?
sf
Yes - NUnit is fine for this
Samuel Jack
+2  A: 

You're exactly right- mocking the repository does bypass the concrete implementation. That's the point.

Unit testing is not the same thing as functional testing. Your mock object can be set up to return whatever you explicitly define, then you test to ensure that constant inputs from your mock lead to expected results.

Dave Swersky
Ok, i'm with you. My intention was to inject a representation of the db to replace the context in order to test the repository methods themselves. Would this not be a good thing to do?
sf
You could do that, but that's really what mocking is for. The idea is that you want to have coverage for each major path of your business logic code, so wire up a mock in each test to return results that test those paths. This will make your tests small and tight.
Dave Swersky
Cheers. I guess I've got a mix up in the terms used. How would I go about creating the Mock in order to test the repository?
sf
Depends on what mocking tool you use. The syntax is similar between them. What you're doing with the mock is creating a "fake" object where you "lock" methods on the mock to return the same result every time. Look into NMock and Moq, those are the .NET-based mocking tools I've seen and used before.
Dave Swersky
+1  A: 

With your two classes (ProductsRepository, ProductsController), you should have two sets of tests. One set of tests for each class.

When (unit) testing the ProductsController, you should mock its dependencies (in this case, the IProductsRepository). Bypassing the concrete implementations of the dependencies is the point.

There will be a completely different set of (integration) tests to validate that the ProductsRepository can hit the database and return correct data. In these integration tests you won't mock anything, since what you're testing is the interaction between a real repository with the actual database.

Eric King