web-dev-qa-db-ja.com

DbEntityEntryのモックまたは偽造、または新しいDbEntityEntryの作成

私の他のものに続いて DbContext.Setのモックに関する質問 EFコードを最初にモックすることについて別の質問があります。

これで、次のような更新のメソッドができました。

_if (entity == null)
    throw new ArgumentNullException("entity");

Context.GetIDbSet<T>().Attach(entity);
Context.Entry(entity).State = EntityState.Modified;
Context.CommitChanges();

return entity;
_

コンテキストは、自分のDbContextのインターフェースです。

私が実行している問題は、どのように処理するかです

Context.Entry(entity).State

私はこのコードをステップ実行しましたが、Contextインターフェースの実装として実際のライブDbContextがある場合に機能します。しかし、私が偽のコンテキストをそこに置いたとき、私はそれをどのように処理するかわかりません。

DbEntityEntryクラスにはコンストラクターがないため、偽のコンテキストで新しいコンストラクターを作成することはできません。

CodeFirstソリューションでDbEntityEntryをモックまたは偽造することに成功した人はいますか?

または、状態の変化を処理するより良い方法はありますか?

60
taylonr

他の場合と同様に、必要なのは間接レベルをさらに追加することです。

interface ISalesContext
{
    IDbSet<T> GetIDbSet<T>();
    void SetModified(object entity)
}

class SalesContext : DbContext, ISalesContext
{
    public IDbSet<T> GetIDbSet<T>()
    {
        return Set<T>();
    }

    public void SetModified(object entity)
    {
        Entry(entity).State = EntityState.Modified;
    }
}

したがって、実装を呼び出す代わりに、SetModifiedを呼び出すだけです。

93
Diego Mijelshon

Moqを使用して単体テストを行う必要があるときにこの質問を見つけました。独自のインターフェースは必要ありません。特定のフィールドを変更しないように設定したかったのですが、メソッドSetModifiedをオブジェクトでも使用できます。

DbContext:

public class AppDbContext : DbContext
{   
    ...
    public virtual void SetModified(GuidEntityBase entity)
    {
        Entry(entity).State = EntityState.Modified;
        Entry(entity).Property(x => x.CreatedDate).IsModified = false;
        Entry(entity).Property(x => x.CreatedBy).IsModified = false;
    }
    ...
}

テスト:

var mockContext = new Mock<AppDbContext>();
mockContext.Setup(c => c.MyDbSet).Returns(mockMyDbSet.Object);
mockContext.Setup(c => c.SetModified(It.IsAny<GuidEntityBase>()));
0
Ogglas