Sabrina S
Sabrina S

Reputation: 447

ASP.NET MVC 3, Ninject, Moq: instantiating mock repository outside unit test class

I've seen a number of samples on how to set up a unit test class for ASP.NET MVC 3 using Ninject and Moq, but they all involve building a mock repository inside the test class.

What I'd like to do is build the mock repository on app start or load - so, perhaps in Global.asax.cs - and pass this to my test class instead. That way I can change to a session-state repository or a database repository in my Ninject AllBindings() method without having to change the unit test class. I already have this in app start:

ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory());

I can even grasp putting a Bind command in global.asax.cs, but how would it get passed to the test class? When you select Test > Run does it even go through global.asax.cs? I guess I'm not sure of what context, if any, calls the test class. I can't wrap my head around how to do this, and I haven't seen any examples that go about creating the repository first and then passing it to the test class.

Is it possible, and if so, how can it be done? Thanks in advance for any advice!

Upvotes: 0

Views: 835

Answers (2)

Christian Horsdal
Christian Horsdal

Reputation: 4932

Instead of using Global.asax (for the reasons Darin Dimitri notes) you could create either a base class for your test or a tetst utility class of sorts. Or you could just drop NInject for the test and do the dependency injection by hand in your tests. I would probaly prefer the manual approach for most tests.

Having said that; if you choose to create a base classe for your tests you could do all your NInjects setup there and then have your test classes inherit from there. That way you'd have your test NInject setup run before every test. Using Xunit.NET, this would be along the lines of:

public class TestBase
{
    public TestBase()
    {
        // Ninject setup for tests
    }
 }

public class ATestClass : TestBase
{
    [Fact]
    public void ATestCase()
    {
       // do your test using the test Ninject setup
    }
}

Upvotes: 1

Darin Dimitrov
Darin Dimitrov

Reputation: 1038830

What I'd like to do is build the mock repository on app start or load - so, perhaps in Global.asax.cs - and pass this to my test class instead.

Erm, wait, I think you are missing the whole point of unit testing. A unit test resides in a separate project that is not related to a running ASP.NET application. The Global.asax is used only by the ASP.NET application.

In your unit test you should test the different classes of your system in isolation, without relying on any ASP.NET specific classes. And if those classes depend on some other layers, such as for example a controller depending on a repository or a service layer, you could use a mock framework to define expectations to this dependency in order to test the controller in isolation. This works only if the dependency is expressed through an interface or an abstract class which can be mocked.

Upvotes: 3

Related Questions