2016-07-15 2 views
2

Я использую тестовый модуль ms для тестирования моего проекта, в котором я использую Entity Framework. Я могу дразнить его, используя следующий пример в Msdn Но у меня есть сценарий, где мне нужно использовать транзакции в рамках сущности В следующим образомЕдиница измерения структуры объекта с мс модульной тестовой средой

Var tran = testdbcontext.Database.BeginTransaction() 

и тест не пройден, как база данных является недействительным для testdbcontext ,

Мне интересно, если мы можем высмеивать его как-то, чтобы получить эту рабочую

ответ

1

Используя связанную статью MSDN для справки вы заметите, что они отведенной DbContext. Используя это же мышление, вы должны также отвлечь творение Сделки.

Сначала создайте абстракцию ожидаемой функциональности для объекта транзакции.

/// <summary> 
/// Wraps access to the transaction object on the underlying store connection 
/// </summary> 
public interface IDbContextTransaction : IDisposable { 
    /// <summary> 
    /// Commits the underlying store transaction 
    /// </summary> 
    void Commit(); 
    /// <summary> 
    /// Rolls back the underlying store transaction 
    /// </summary> 
    void Rollback(); 
} 

Это отражает функциональность, которую вы хотите от транзакции базы данных.

Для производства у вас может быть такая реализация, которая обертывает фактический объект, который вы хотите использовать.

public class DbContextTransactionWrapper : IDbContextTransaction { 
    private DbContextTransaction dbContextTransaction; 

    public DbContextTransactionWrapper(DbContextTransaction dbContextTransaction) { 
     this.dbContextTransaction = dbContextTransaction; 
    } 

    public void Commit() { 
     dbContextTransaction.Commit(); 
    } 

    public void Rollback() { 
     dbContextTransaction.Rollback(); 
    } 

    public void Dispose() { 
     if(dbContextTransaction != null) { 
      dbContextTransaction.Dispose(); 
      dbContextTransaction = null; 
     } 
    } 
} 

Абстракции DbContext будет включать в себя возможность создавать транзакции ...

public interface IStoreAppContext : IDisposable { 
    DbSet<Product> Products { get; } 
    int SaveChanges(); 
    void MarkAsModified(Product item); 
    IDbContextTransaction BeginTransaction(); 
} 

и реализация будет использовать обертку

public class StoreAppContext : DbContext, IStoreAppContext 
{ 
    public StoreAppContext() : base("name=StoreAppContext") 
    { 
    } 

    public DbSet<Product> Products { get; set; } 

    public void MarkAsModified(Product item) 
    { 
     Entry(item).State = EntityState.Modified; 
    } 

    public IDbContextTransaction BeginTransaction() { 
     return new DbContextTransactionWrapper(Database.BeginTransaction()); 
    } 
} 

Таким образом, в ваших модульных тестов вы можете высмеивать создание транзакции через насмешливую структуру или поддельную реализацию, и вы будете называть ее непосредственно на абстрактном DbContext.

Предполагая testdbcontext имеет тип IStoreAppContext, то ваш звонок будет выглядеть ...

IDbContextTransaction tran = testdbcontext.BeginTransaction(); 

это даст вам доступ к tran.Commit() и tran.Rollback(), которые определены в интерфейсе и позволит легко тестирования.

+0

Спасибо, попробуй это – Vivekh

+0

Какой должен быть код для commit()? – Vivekh

+0

У транзакции есть метод Completed(), который используется для фиксации – Nkosi

Смежные вопросы