4

I am creating a small proof of concept asp.net web api 2 service with entity framework code first. The controller's constructor looks like

public AccountController: ApiController
{
    private readonly DbContext context;
    public AccountController(DbContext _context){
        context = _context;
    }
    public AccountController(){context = new ApplicationContext();}
}

I need to unit test my controllers. How can I mock the DbContext class. Is there a simple way of doing this? I want to avoid all that repository pattern with lot of interfaces. Because it will be a way overkill for this prototype.

3
  • 1
    If it's a prototype, why bother with Dynamic Injection then? Commented Oct 23, 2014 at 22:45
  • I don't really bother the dynamic injection but I want the ability to unit test it. basically, its not injected currently because controllers are currently instantiated using no argument constructor. But I need a way to mock dbcontext which is essentially a dependency for my controller. Without mocking it, how can I unit test my controller? Commented Oct 24, 2014 at 11:16
  • Wrap it in an IUnitOfWork interface is what I normally do, which exposes the core DBContext methods. I've also modified the T4 templates to generate an interface for the DBContext in addition to the class; working on a blog post on that. Not done yet. Commented Oct 24, 2014 at 12:08

1 Answer 1

1

Its usually something like this if you use Nunit and Moq.

    [TestFixture]
    public class AccountControllerTest
    {
      private Mock<DbContext> mockContext;

      private AccountController sut;


      [SetUp]
      public void TestSetup()
      {
        mockContext = new Mock<DbContext>();
        var account = new Account() { Id = 123, Name = "Test Account" };
        mockContext.SetUp(x => x.GetAccountOnContext()).Returns(account);
        sut = new Controller(mockContext.Object) { Request = new HttpRequestMessage() };
        sut.Request.Properties.Add(HttpPropertyKeys.HttpConfigurationKey, new HttpConfiguration());
      }

      [Test]
      public void ControllerMethod_GetLogin_Test()
      {
        // assuming GetLogin calls GetAccount on DbContext()

        var response = sut.GetLogin(someAccount);
        Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
        mockContext.Verify();
      }
   }

You basically want to mock out your external dependencies and test just what the SUT (System Under Test) is supposed to do. I would also strongly encourage to look at Fakes instead of mocks. In general fakes result in less brittle tests.

So in this case, you could have a FakeDbContext() that you can pass to the tests. The FakeDbContext() will behave more like the actual DbContext() but will do all those operations in-memory, so that your tests don't have a dependency with a real database.

Depending on the database you use, you can also look at starting an embedded version of the real database as a part of your tests. Just have to make sure to do the necessary stopping and clean up of the test database records after the test run is complete in the TearDown() method.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.