Johnson Duru
Johnson Duru

Reputation: 682

How to unit test ASP.NET MVC Controller without Using Repository Pattern

I am just wondering if there a way I can unit test some of my controller Action in MVC without using Repository pattern. I have develop an ASP.NET MVC site but did this without unit testing at the initial stage. Now I want to demonstrate some unit test to my tutor using may be two or more action in my controller. Most of my actions logic get data from database and one controller get data from different tables i.e actions in one controller read from different table. which I think that can be test using Generic Repository pattern. As a beginner I found that I can only unit test a code that is not coming from database but unfortunately most of the code in my controller Actions come from database. i am using the default test tool in visual Studio and EF code first approach for my database.
for example i will like to unit test only the below Actions without having to unit test other action that are in the same controller.

public ActionResult Index()
    {
        var model = _db.PhotoGallery;
        return View(model);
    }

This is just for demonstration purpose.

Upvotes: 8

Views: 2814

Answers (3)

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236228

That's what called testable code :) When you perform unit testing, you need to be sure, that only reason of failing test is changing in SUT (system under test, or class being tested) implementation. Of course, it could be broken when dependency API changes (thats OK, you should modify SUT to use new API), but it never should fail if dependency implementations changed. Thats why mocking and stubbing used.

But if you want to mock dependency, you should not create it inside SUT. It should be injected into SUT (constructor, property of parameter injection).

So, back to your case:

  • if you want to have testable class, you have to inject dependency (db)
  • dependency should be mocked
  • you not forced to use Repository pattern. If you can mock your db class, just mock it. Or use any other data access abstraction

Upvotes: 2

BrokenGlass
BrokenGlass

Reputation: 160902

Without removing the direct dependency to the database in you controller methods you will not be able to unit test these methods.

The overall recommended way of doing this would be using an IOC Container (e.g. Ninject) in combination with MVC that allows you to pass the data you need to the constructor of your controller. That "data object" must not be tied to the database, typically it is either just a POCO object or passed as an interface.

In your unit tests you can then substitute these dependencies using an in-memory data object constructed just for your unit tests, typically "mocked" using a mocking framework (e.g. Rhino Mocks or Moq).

Using this approach you not only make your controllers unit-testable but also will end up with very loosely coupled code, a benefit that might pay off for later development.

Upvotes: 6

StriplingWarrior
StriplingWarrior

Reputation: 156524

By definition, a unit test should only affect the method that it calls. If you can find a way to mock your _db object so that you're not actually causing a database round-trip, then you can unit test this method that relies on it. Otherwise, no.

Is your _db field's type an interface? Is it being provided via injection? If so, it's likely that you can unit test this method.

Upvotes: 6

Related Questions