我有一个应用程序,其中包含使用Entity Framework 4.2 Code First和MySQL数据库处理数据的方法。我正在尝试找出为这些方法编写MSTest单元测试的好方法。例如:如何为使用实体框架4.2的代码编写单元测试?
的DataModel:
public class User
{
public User() { }
[Key]
public int UserID { get; set; }
public string Role { get; set; }
}
public class AppDbContext : DbContext
{
public DbSet<User> Users { get; set; }
}
业务层:
public class Bus
{
public bool UserIsInRole(int userID, string role)
{
using(var context = new AppDbContext())
{
User user = context.Users.SingleOrDefault(p => p.UserID == userID);
if (user == null)
return false;
return user.Roles.Split(',').Contains(role);
}
}
}
我想写一组单元测试的UserIsInRole功能,但我想尝试自己从隔离实际上必须读取和写入实际的数据库,因为我无法在测试之前保证其状态。仅仅为这个测试设置/拆除数据库将需要很长时间。
我遇到过很多关于使用假DbContext的文章,比如here,here和here,但它们都似乎有一些优点和缺点。一群人说,不应该针对EF编写单元测试,并且这属于集成测试,并且任何假的DbContext都不能像可接受测试的目的那样表现得足够真实。
我认为这样的代码位于参数中间的某个位置。理想情况下,我想创建一组表示所需数据的临时内存对象,而无需将其实际存储到数据库中。
你将如何更改上面写的一组验证UserIsInRole方法测试:
- 返回false如果用户ID中不存在的用户收集 。
- 如果用户不包含 所需的角色,则返回false。
- 如果用户具有所需的角色,则返回true。
请记住,这是一个简单的例子,该代码实际上可以包含任意复杂的多个查询,所以我希望能找到的东西有点比更全面,比如说,每个查询移动到这是一个虚函数由测试框架替换以返回预定义的用户记录。
这是我正在考虑的事情。它将允许任何代码从数据源创建所需的任何查询。我担心的是,查询可能与在Linq到Entities之间返回的数据以及Linq到对象的(我认为)有什么不同。您对结果查询兼容性有任何经验吗?例如,编译良好并且通过测试但不能抵抗真实数据(区分大小写,不受支持的函数,空行为,结果分组)的情况。显然,无论如何,都需要一定程度的集成测试。 – 2012-02-22 20:19:59
我只是在我的代码中尝试了这种方法。但是,我使用的功能在IQueryable <>中不受支持,例如Create(),Add(),Remove()等。它看起来像我还需要为每个实体创建某种接口,或者将这些移动到IAppDomain接口。 – 2012-02-22 21:07:49
@DanC - 你也可以公开IDbSet而不是IQueryable。这给你所有他的选择,但允许你创建一个虚假的实现 – Polity 2012-02-23 02:07:28