RobVious
RobVious

Reputation: 12915

Unit Testing an MVC4 Application Service Layer

I've spent the past two days starting and restarting this learning process because I really don't know how to get started.

I have an MVC4 application with three layers: Web, Services, and Core. Controllers send requests to the Service layer, which provide info that the controllers use to hydrate the viewModels for the view.

I have the following methods in my service layer:

public interface ISetServices
{
    List<Set> GetBreadcrumbs(int? parentSetId);
    Set GetSet(int? setId);
    Set CreateSet(string name, string details, int? parentSetId);
    void DeleteSet(int? setId);

    Card GetCard(int? cardId);
    Card CreateCard(List<string> sides, string details, int? parentSetId);
    void DeleteCard(int? cardId);

    Side GetSide(int? sideId);
    List<String> GetSides(Card card);
    Side CreateSide(Card card, string content);
    void DeleteSide (int? sideId);

}

I'm trying to figure out how I can create a Unit Test Class Library to test these functions.

When the tests are run, I would like a TestDatabase to be dropped (if it exists) and recreated, and seeded with data. I have a "protected" seed method in my Core project along with a - can I use this? If so, how?

Everywhere I read says to never use a database in your tests, but I can't quite figure out what the point of a test is then. These services are for accessing and updating the database... don't I need a database to test?

I've created a Project.Services.Tests unit testing project, but don't know how to wire everything up. I'd like to do it with code and not configuration files if possible... any examples or pointers would be MUCH appreciated.

Upvotes: 3

Views: 748

Answers (1)

Dawid Kowalski
Dawid Kowalski

Reputation: 1247

There are many aspects to this problem, let me try to approach some:

  • Unit testing is about testing a unit of code, smallest possible testable piece of code but testing unit of code with it's interaction with database is an integration test problem
  • One approach to this problem by using repository pattern - it is an abstraction layer over your data access layer. Your service interface looks more like a repository pattern implementation, google around about it more.
  • Some people do not test internals of repository pattern, they just assert calls against it's interface. Database tests are considered an integration test problem.
  • Some people hit their database directly by writing SetUp and TearDown steps in their unit tests, where usually you would insert appropriate data in a SetUp and TearDown would clean it all up to the previous state, but be aware - they can get pretty slow and make your unit testing a pain.
  • Other approach would be to configure your tests to use different database - for example SQLCE. For some ORMs database swapping might be quite easy. This is faster than hitting 'full' database, and seem cleaner, but databases implementations have differences that sooner or later will surface and make your unit testing painful...
  • Currently with the raise of NoSQL solutions accessing database directly can get very easy because quite often they have their memory counterparts (like RavenDB)

I realize it might be a bit overwhelming at the beginning, but again, this problem has many aspects. How about you post your source code to github and share it here ?

Upvotes: 2

Related Questions