I've been researching this topic for weeks. I've found a lot of material but nothing which I feel answers the question completely. A lot of the information is years old and might not apply.
I'm building an MVC4 application that is a rebuild of an existing but out-dated application. The database already exists (and therefore database-first approach), is large and is complex. Ideally what I want is a fake "entity" object that is identical to my main entity object but uses a different, "mock" or in-memory database of some sort so that I can generate a bunch of fake data, run the tests and receive feedback. For example:
FakeEntities _db = new FakeEntities();
// test a controller action
From what I understand so far I should be using integration testing. According to this post by Ladislav Mrnka integration testing means testing controller actions and means less problems with LINQ-to-entities and LINQ-to-objects
if you mock the repository you will use Linq-To-Objects and you will have a green test but if you run the application with Linq-To-Entities you will get an exception
I know what he means and I can agree - I'd like to ensure I'm always using Linq-To-Entities and a real (or close to real) database.
I've read a lot about the repository pattern and this blog by linush looks to be pretty close to what I might be attempting. In fact I've already created a dummy project in which I tested creating a generic repository and successfully used Entity Framework and a "mock" DbContext which relied on in-memory ObjectSets.
My problem with this approach is
Your question is itself filled with contradictions. For example, you say that it is important to test stored procedures, but you also want to be database agnostic. Which one is it?
If you really want to be database agnostic, get rid of your stored procedures and make your testing environment much simpler. You will be able to use a completely in-memory database (like Apache Derby) as part of your test environment. That makes it easier to script inside Jenkins or whatever your CI environment is.
Next you need to decide what you are wanting to test. If you are wrapping unit tests around your controllers, then make sure you write your controllers to be testable. Since you are starting from scratch, this should be easy to do. Use concepts like injection to make it easy to swap parts of your functionality out for mock implementations. Use a mock object framework (as you discovered) to create a set of objects which you pass to the controller being tested.
All the above is good if you can test your controllers on their own. But if you are building a highly interdependent stack with database stored procedures interacting deeply with controllers and views, then this isn't going to work well. Either redesign your approach so that unit testing is possible or move to functional testing.
Selenium is one of the best known and used functional test environments for web applications. You can test the entire system from end to end. Even better, you can start writing Selenium tests around your existing old application, and then ensure that the new implementation reproduces the same features during your rewrite.
I wrote two articles about how to use Unit Of Work
and Repository Pattern
with both LINQ and Entity Framework. A great way when it comes to testing/mocking. Take a look at them.
http://gaui.is/how-to-mock-the-datacontext-entity-framework/
http://gaui.is/how-to-mock-the-datacontext-linq/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With