在Web api 2控制器的构造函数中注入DbContext

时间:2014-10-23 20:43:10

标签: asp.net entity-framework asp.net-web-api

我首先使用实体​​框架代码创建一个小概念证明asp.net web api 2服务。控制器的构造函数看起来像

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

我需要对我的控制器进行单元测试。我如何模拟DbContext类。有一个简单的方法吗?我想避免使用大量接口的所有存储库模式。因为这将成为这种原型的一种过度杀伤力。

1 个答案:

答案 0 :(得分:1)

如果你使用Nunit和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();
      }
   }

您基本上想要模拟外部依赖项并测试SUT(系统测试)应该做什么。我也强烈建议你看看Fakes而不是嘲笑。一般来说,假货会导致脆弱性测试。

所以在这种情况下,你可以有一个可以传递给测试的FakeDbContext()。 FakeDbContext()的行为更像实际的DbContext(),但会在内存中执行所有这些操作,因此您的测试不会与真实数据库有依赖关系。

根据您使用的数据库,您还可以查看启动嵌入式版本的真实数据库作为测试的一部分。在TearDown()方法中完成测试运行后,只需确保执行必要的停止和清理测试数据库记录。