首页 文章

使用从IdentityDbContext继承的上下文对Entity Framework 6进行单元测试

提问于
浏览
4

我正在寻找使用instructions provided here使用Entity Framework 6对一些方法进行单元测试 .

我的设置略有不同 - 我也使用ASP.Net Identity(使用EF的默认实现) . 因此,我的上下文继承自IdentityDbContext .

当我运行测试时,我得到一个例外,其中包含以下详细信息:

Castle.Proxies.IdentityUserLogin: : EntityType 'IdentityUserLogin' has no key defined. Define the key for this EntityType.    
Castle.Proxies.IdentityUserRole: : EntityType 'IdentityUserRole' has no key defined. Define the key for this EntityType.    
IdentityUserLogins: EntityType: EntitySet 'IdentityUserLogins' is based on type 'IdentityUserLogin' that has no keys defined.    
IdentityUserRoles: EntityType: EntitySet 'IdentityUserRoles' is based on type 'IdentityUserRole' that has no keys defined.

我已经读过,在正常使用中,这些是在默认的OnModelCreating方法中设置的 .

但是,有人可以提供有关在上面链接的方法中说明的模拟上下文中处理此问题的建议吗?

谢谢

安迪

1 回答

  • 0

    正如那篇文章所指出的那样,当你模拟EF类型时,你会完全改变它们的行为:查询将作为LINQ-to-Objects而不是LINQ-to-SQL执行 . 这意味着您可以轻松编写单元测试,以便在现实世界中使用时失败的代码 . 一个很好的例子是:

    context.Foos.Where(candidate => SomePredicate(candidate));
    

    这意味着您需要完全理解有效的LINQ-to-SQL表达式来编写单元测试,但是您正在编写这些单元测试,因为您想要验证您的理解 . 那真的给你买了什么?你从这些单元测试中获得了多少 Value ?我从一个曾经花了很多时间嘲笑我的EF层的人的角度来说这个,只是发现一旦数据库涉及到代码是错误的 .

    在我看来,更好的测试策略是创建 Gateway 类,充当您的 DbContext 与该上下文的消费者之间的中介 .

    class FooGateway : IFooGateway
    {
        IEnumerable<Foo> GetFoosThatObeySomePredicate() { /* ... */ }
    }
    

    Gateway 公开了可以有效模拟的接口 . 在数据消耗类中使用这些接口,以便您可以编写高质量的单元测试,然后接受编写集成测试以自行测试 Gateway 类:这些测试需要一个真实的数据库,因此您需要用于创建数据库的基础结构部分测试 .

相关问题