views:

53

answers:

3

I am trying to use the fluent test helpers to test an AbstractRestfulFluentController

public class CustomerController : AbstractRestfulFluentController
{
    private readonly IService<Customer> _customerService;
    private readonly IService<CustomerAddress> _addressService;

    public CustomerController(IService<Customer> customerService, IService<CustomerAddress> addressService)
    {
        //Assume we use these in other actions
        _customerService = customerService;
        _addressService = addressService;
    }

    public ActionResult Index()
    {
        return View();
    }
}

As you can see I am injecting some services into the controller and resolving them using IOC. My problem is that all the examples I have found using the fluent test methods in mvccontrib don't work without a paramaterless controller.

public void SuccessfulIndex()
    {
        GivenController.As<CustomerController>()
            .ShouldRenderItself(RestfulAction.Index)
            .WhenCalling(x => x.Index());
    }

I'm not sure what I need to do in order to be able to use IOC with the fluent test techniques in mvccontrib. I have found a few comments that it is possible but haven't found anything. What can I do in order to actually use IOC and fluent tests?

A: 

Have you tried property injection instead of constructor injection?

http://ninject.codeplex.com/wikipage?title=Injection%20Patterns

Dave Swersky
I have not. I have been trying to stick with a common pattern across the application layers using constructor injection. I would like to stick with that pattern if possible. If it isn't possible then this could work and I will mark it as the answer.
Firestrand
I believe the test helpers are open-source, you might also try digging in and see if you can find a clean extension point.
Dave Swersky
A: 

I am currently having a weird ninject issue that I just posted about, but this should at least point you in the right direction...all the code is there for setting up the dependency injection.

http://stackoverflow.com/questions/3909452/unit-testing-asp-net-mvc-controllers-with-ninject

Luke
A: 

You could write a method which allows you to provide the instance of the controller:

public static class GivenController
{
    public static ActionExpectations<T> As<T>(T controller) where T: Controller, new()
    {
        return new ActionExpectations<T> { MockController = controller };
    }
}

And then in your unit test:

var controller = CreateMockedCustomerController();
GivenController
    .As<CustomerController>(controller)
    .ShouldRenderItself(RestfulAction.Index)
    .WhenCalling(x => x.Index());

The requirement is that the controller should be a mock object which in my opinion is not a very clean approach (testing a mocked object). You could create it like this:

var controller =  MockRepository
    .GeneratePartialMock<CustomerController>(new object[] { dep1, dep2 });

Notice how dependencies are passed to the constructor.

Darin Dimitrov
This looks to be my best option so far. If I have to make any additional changes I will post an update. Once verified I will mark it complete.
Firestrand