我刚刚开始使用实体框架(v4)和Linq。
我有一个实体数据模型,它是从数据库中生成的。然后,我实现了存储库类,以便为我的实体实现业务逻辑,它们包含用于与实体/数据库交互的LINQ查询。
在不影响数据库的情况下,对存储库类中的方法/函数进行单元测试的最简单方法是什么?
您可以针对内存数据库运行测试。检查此问题
找到一个允许您创建实体库的框架。这在一开始需要时间,但从长远来看会有回报。
如果您可以将IDbSet
传递到它正在查询的存储库中,那么您可以轻松地编写自己的IDbSet
存根实现,该实现可以从映射到IQueryable
的内存集合中读取和写入,也可以使用mocking框架为您完成此操作。
在您的生产代码中,您从实际的DbContext
传入IDbSet
;在您的测试代码中,您传入这个存根。
如果测试中的存储库引用了DbContext
,那么您可能需要进行重构,使其仅引用单个IDbSet
。
我假设您不想在测试中加载/保存任何实体(即:只测试业务逻辑,而不是持久层)。在这种情况下,您将需要一种轻松生成(和重用)测试"存根"的方法。imo最简单的方法是为您的各种实体创建一些工厂,这些工厂返回一些简单(但有意义)的实体。
例如,如果你正在测试你的用户引擎,你可能希望有一个测试工厂来生成不同类型的用户,可能是来自威斯康星州的用户,或者姓氏很长的用户,或没有朋友的用户,而不是有100个朋友的用户等
public static class UserStubFactory {
static User NewUserWithLongLastName(int letterCount) { //return user with long last name }
static User NewUserWithXFriends(int count) { //return user w/ X friends }
}
然后,当您生成其他测试存根工厂时,您可以开始将它们链接在一起。所以,也许你想测试一个姓氏很长的用户,然后在你的系统中对他们进行一些其他操作。现在你已经有了TestStub,所以你可以简单地调用NewUserWithLongLastName()并通过你的引擎传递它。
如果你不喜欢这种方法,你也可以用构造函数语法动态创建它们。
User newUser = new User() { LastName ="HOLYCOWTHISISAVERYYLONGLASTNAME"; }
但我更喜欢工厂,因为它们的可重复使用性因素。