EF4代码第一,TDD,CRUD和事务 [英] EF4 Code First, TDD, CRUD, and Transactions

查看:206
本文介绍了EF4代码第一,TDD,CRUD和事务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

过去,在创建数据访问/存储库代码时,我已经为简单的CRUD操作编写了单元测试:

In the past, I've written unit tests for simple CRUD operations when creating data access/repository code that look something like this:

using(var connection = new WhateverConnection(connectionString))
{
    connection.Open();
    using(var transaction = connection.BeginTransaction())
    {
        try
        {
            //test the CRUD operation
        }
        finally
        {
            //gets rid of any stuff created during the test
            transaction.Rollback();
        }
    }
}

我正在搞乱EF4代码首先今天,我意识到我不知道这个测试场景如何在实体框架词典中翻译。看来,如果我调用 DbContext.SaveChanges(),它会保存提交,而不管 AcceptAllChanges ()被调用。即使使用 ObjectContext 而不是 DbContext ,我无法确定如何在不手动清除的情况下重新创建这个简单的测试场景创建任何模拟/测试对象。我已经阅读了 MSDN上的这篇文章,但是 / code>还没有一个回滚类型方法。我使用 TransactionScope ,从不调用完成?在单元测试期间是否有另一种使用DbContext和/或ObjectContext的方法或方式进行回滚?我需要用EF4 Code First完全重新调整我的TDD思维吗?

I was messing around with EF4 Code First today, and I realized that I have no idea how this testing scenario translates in the Entity Framework lexicon. It seems that, if I call DbContext.SaveChanges(), it saves and commits, regardless of whether or not AcceptAllChanges() was called. Even using ObjectContext instead of DbContext, I can't figure out how this simple test scenario can be recreated without manually cleaning up any mock/test objects created. I did read this article on MSDN, but TransactionScope doesn't really have a Rollback type method either. Do I use TransactionScope and never call Complete? Is there another method or manner of using DbContext and/or ObjectContext in order to Rollback during unit tests? Do I need to completely re-adjust my thinking for TDD with EF4 Code First?

推荐答案

ObjectContext 本身不会暴露事务行为。你自己必须在交易中包装EF代码。简单的方法是使用 TransactionScope 。如果您不调用范围上的完成方法并处理它,它将执行回滚。我们通常使用基类进行这种集成测试:

ObjectContext itself does not expose transactional behavior. You have to wrap EF code in transaction by yourself. The easy way to do it is using TransactionScope. If you don't call Complete method on the scope and dispose it, it will perform rollback. We are usually using base class for this type of integration tests:

[TestClass]
public abstract class TransactionTestBase
{
    private TransactionScope scope = null;

    [TestInitialize]
    public virtual void TestInitialize()
    {
      scope = new TransactionScope(TransactionScopeOption.RequiresNew,
          new TransactionOptions()
              {
                  IsolationLevel = IsolationLevel.ReadUncommitted
              });
    }

    [TestCleanup]
    public virtual void TestCleanup()
    {
        if (scope != null)
        {
            scope.Dispose();
            scope = null;
        }
    }
}

所有测试类派生自类。 TestInitialize 在派生类中的每个 TestMethod 之前调用, TestCleanup 在每个 TestMethod 后调用,所以您的测试根本不需要处理交易。

All test classes derive from this class. TestInitialize is called before each TestMethod in derived class and TestCleanup is called after each TestMethod so your tests don't have to deal with transaction at all.

这篇关于EF4代码第一,TDD,CRUD和事务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆