我熟悉ASP .NET MVC应用程序中用于测试控制器和业务逻辑的技术.
我们的应用程序中的数据访问集中在特殊服务中,这些服务是松散耦合的,使用接口并通过实体框架与实际数据库一起工作.
但是,随着DAL变得越来越复杂,隐藏数据库实现细节并为应用程序代码提供抽象,我们开始关注我们是否能够以任何方式对其进行测试.因为它已经与EF上下文紧密绑定,所以我们不打算引入另一个存储库样式的层,但这也意味着我们不能仅使用伪数据对其进行单元测试.
我想知道是否有可能以某种方式模拟或存根Entity Framework对象上下文,同时能够执行简单的操作,如添加/删除实体和进行查询.
我也在寻找关于它是否是一个好主意(可能非常糟糕)的意见,如果不是,那么一些"智能"数据层测试建议.
我目前有一个项目,我已经开始使用EF4,我回过头来加入单元测试.我正在使用EF4 POCO T4模板和我的模型(数据库)第一个上下文.我正在为我的DAC逻辑使用通用存储库,并为持久性使用工作单元模式.
但是,我遇到了一些理解如何模拟ObjectContext/ObjectSet的问题.我查看了使用本文中的FakeObjectSet<T>示例,但它仍然留下了一些内容,例如自动递增标识和事务回滚.
所以,我试图找到一个好的EF设计,仍然可以完全单元测试.
我的问题是,EF4.1 DbSet是否解决了很多问题,单元测试EF4?有没有很好的综合性文章来设计可完全测试的EF4.1解决方案?
另外,请记住,我需要一个模型优先的解决方案.
提前致谢.
unit-testing entity-framework entity-framework-4 entity-framework-4.1
关于一件事,我已经读了很多(数十篇文章):
如何对其中包含实体框架代码的业务逻辑代码进行单元测试。
我有3层的WCF服务:
我的业务逻辑将DbContext用于所有数据库操作。现在,我所有的实体都是POCO(以前是ObjectContext,但我对此进行了更改)。
我已阅读拉吉斯拉夫Mrnka的答案在这里,并在这里 的原因,我们应该不假\伪造的DbContext。
他说: “这就是为什么我认为处理上下文/ Linq到实体的代码应该包含集成测试并针对实际数据库进行工作的原因。”
并且: “当然,您的方法在某些情况下有效,但单元测试策略必须在所有情况下均有效-要使其起作用,必须将EF和IQueryable完全从已测试的方法移开。”
我的问题是-您如何实现这一目标???
public class TaskManager
{
public void UpdateTaskStatus(
Guid loggedInUserId,
Guid clientId,
Guid taskId,
Guid chosenOptionId,
Boolean isTaskCompleted,
String notes,
Byte[] rowVersion
)
{
using (TransactionScope ts = new TransactionScope())
{
using (CloseDBEntities entities = new CloseDBEntities())
{
User currentUser = entities.Users.SingleOrDefault(us => us.Id == loggedInUserId);
if (currentUser == null)
throw new Exception("Logged …Run Code Online (Sandbox Code Playgroud) 我有一个很好的解耦应用程序和依赖注入的应用程序,它使用Entity Framework 4.1 CodeFirst通过存储库模式公开IQueryable.在测试存储库客户端时,很容易模拟底层数据存储区,但是没有捕获到某类错误:
存储库客户端可以自由地在存储库返回的内容上层叠自己的LINQ谓词,联接等:
{
_myRepository.FindAll().Where( x => x.Id == 3 && SomeMethod(x.Name) == "Hello" );
}
Run Code Online (Sandbox Code Playgroud)
这种查询将在模拟_myRepository的单元测试中成功,因为mock返回内存中的实体集合,而LINQ-to-Objects很乐意调用方法"SomeMethod".它将对真正的数据存储失败,因为"SomeMethod"不会转换为LINQ-to-Entities中的SQL.
我试图找出一种方法,我可以模拟数据集,并导致真正的EF查询提供程序生成(但不执行)SQL.为什么?因为测试应该很快,我不希望它们尽可能地打到真正的数据库.生成SQL将清除这样的翻译问题.
到目前为止,我还没有弄清楚如何做到这一点,因为在我的单元测试中,我最终无法控制查询何时实现.我想我需要提供我自己的IQueryable版本和各种LINQ Queryable扩展方法,或尝试通过提供程序机制挂钩(使用几年前做缓存/跟踪提供程序的示例.)这些似乎很多工作.关于如何实现这一点的任何想法?
.net unit-testing entity-framework mocking repository-pattern