views:

170

answers:

2

This is more of an opinion seeking question, so there may not be a "right" answer, but I would welcome arguments as to why your answer is the "right" one.

Given an MVC application that is using Entity Framework for the persistence engine, a repository layer, a service layer that basically defers to the repository, and a delete method on a controller that looks like this:

    public ActionResult Delete(State model)
    {
        try
        {
            if( model == null )
            {
                return View( model );
            }

            _stateService.Delete( model );

            return RedirectToAction("Index");
        }
        catch
        {
            return View( model );
        }
    }

I am looking for the proper way to Unit Test this. Currently, I have a fake repository that gets used in the service, and my unit test looks like this:

    [TestMethod]
    public void Delete_Post_Passes_With_State_4()
    {
        //Arrange
        var stateService = GetService();
        var stateController = new StateController( stateService );

        ViewResult result = stateController.Delete( 4 ) as ViewResult;
        var model = (State)result.ViewData.Model;

        //Act
        RedirectToRouteResult redirectResult = stateController.Delete( model ) as RedirectToRouteResult;

        stateController = new StateController( stateService );

        var newresult = stateController.Delete( 4 ) as ViewResult;
        var newmodel = (State)newresult.ViewData.Model;

        //Assert
        Assert.AreEqual( redirectResult.RouteValues["action"], "Index" );
        Assert.IsNull( newmodel );
    }

Is this overkill? Do I need to check to see if the record actually got deleted (as I already have Service and Repository tests that verify this)? Should I even use a fake repository here or would it make more sense just to mock the whole thing?

The examples I'm looking at used this model of doing things, and I just copied it, but I'm really open to doing things in a "best practices" way.

Thanks.

+1  A: 

Hi,

I personally in that situation would use a Fake Service.

As from the sound of things you already have service tests so you don't need to test the service delete here just the controller.

As for your other tests I would use a Fake Repository to test the Service layer. As for testing the repository I would have a test database setup to test all the methods and make sure that there is a way to set the database back to its original setup so every time you run the tests your testing against the same data.

Simon G
Agreed. If this code is testing the controller, than the service and repositories should be fakes/stubs.
Patrick Steele
A: 

I agree that if you have tested other layers etc elsewhere there is no need to test the controller.

I would disagree with the answer above in that a database is not in my opinion the best way to test. It's slower than using in memory lists etc but as Simon says, you need to write cleanup code to ensure the database returns to a neutral state.

This means it's less likely you will write and run tests.

Again ypou are not testing the database. You are testing your controller.

Davy
The poster above specified that he would use a test database to test the actual repository code. Certainly, you can test most levels by using fakes, but when it comes to actually testing your repository code (the code that actually talks to your database), the only way to test it is to have it actually talk to your database. If you replace the repository with a fake, then you aren't really testing the repository. You are testing the fake...
Brian McCord