Reputation: 682
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
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:
Upvotes: 2
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
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