[解決済み] MoqでEF DbContextをモック化する
2023-04-29 01:33:18
質問
モック化されたDbContextを使ったサービスのユニットテストを作成しようとしています。私はインターフェイスを作成しました
IDbContext
を作成し、以下のような機能を持たせました。
public interface IDbContext : IDisposable
{
IDbSet<T> Set<T>() where T : class;
DbEntityEntry<T> Entry<T>(T entity) where T : class;
int SaveChanges();
}
私の実際のコンテキストは、このインターフェイスを実装しています
IDbContext
そして
DbContext
.
今、私は
IDbSet<T>
をモックしています。
List<User>
を返します。
[TestMethod]
public void TestGetAllUsers()
{
// Arrange
var mock = new Mock<IDbContext>();
mock.Setup(x => x.Set<User>())
.Returns(new List<User>
{
new User { ID = 1 }
});
UserService userService = new UserService(mock.Object);
// Act
var allUsers = userService.GetAllUsers();
// Assert
Assert.AreEqual(1, allUsers.Count());
}
でいつもこのエラーが出ます。
.Returns
:
The best overloaded method match for
'Moq.Language.IReturns<AuthAPI.Repositories.IDbContext,System.Data.Entity.IDbSet<AuthAPI.Models.Entities.User>>.Returns(System.Func<System.Data.Entity.IDbSet<AuthAPI.Models.Entities.User>>)'
has some invalid arguments
どのように解決するのですか?
私は、この問題を解決するために
FakeDbSet<T>
を実装したクラスを作成することで解決しました。
IDbSet<T>
public class FakeDbSet<T> : IDbSet<T> where T : class
{
ObservableCollection<T> _data;
IQueryable _query;
public FakeDbSet()
{
_data = new ObservableCollection<T>();
_query = _data.AsQueryable();
}
public virtual T Find(params object[] keyValues)
{
throw new NotImplementedException("Derive from FakeDbSet<T> and override Find");
}
public T Add(T item)
{
_data.Add(item);
return item;
}
public T Remove(T item)
{
_data.Remove(item);
return item;
}
public T Attach(T item)
{
_data.Add(item);
return item;
}
public T Detach(T item)
{
_data.Remove(item);
return item;
}
public T Create()
{
return Activator.CreateInstance<T>();
}
public TDerivedEntity Create<TDerivedEntity>() where TDerivedEntity : class, T
{
return Activator.CreateInstance<TDerivedEntity>();
}
public ObservableCollection<T> Local
{
get { return _data; }
}
Type IQueryable.ElementType
{
get { return _query.ElementType; }
}
System.Linq.Expressions.Expression IQueryable.Expression
{
get { return _query.Expression; }
}
IQueryProvider IQueryable.Provider
{
get { return _query.Provider; }
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return _data.GetEnumerator();
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return _data.GetEnumerator();
}
}
これで、私のテストは次のようになります。
[TestMethod]
public void TestGetAllUsers()
{
//Arrange
var mock = new Mock<IDbContext>();
mock.Setup(x => x.Set<User>())
.Returns(new FakeDbSet<User>
{
new User { ID = 1 }
});
UserService userService = new UserService(mock.Object);
// Act
var allUsers = userService.GetAllUsers();
// Assert
Assert.AreEqual(1, allUsers.Count());
}
関連
-
[解決済み】"指定されたパスのフォーマットはサポートされていません。"
-
[解決済み】別のスレッドがこのオブジェクトを所有しているため、呼び出し側のスレッドはこのオブジェクトにアクセスできない
-
[解決済み] フェイク、モッキング、スタビングの違いとは?
-
[解決済み] モッキングとは?
-
[解決済み] Moqでメソッドが呼び出されていないことを確認する方法は?
-
[解決済み] Mockitoで静的メソッドをモックする
-
[解決済み] Moqにタスクを返すように指示するにはどうしたらいいですか?
-
[解決済み] [Solved] Webリクエストごとに1つのDbContext...なぜ?
-
[解決済み】Moqで1回目と2回目の戻り値が違う件
-
[解決済み】Moqで特定のパラメータを検証する
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] [Entity Framework 4.1でエンティティに関連オブジェクトを追加する際に、エンティティオブジェクトをIEntityChangeTracker.の複数のインスタンスから参照できない。
-
[解決済み】文字列が有効な DateTime " format dd/MM/yyyy " として認識されなかった。
-
[解決済み] エンティティタイプ <type> は、現在のコンテキストのモデルの一部ではありません。
-
[解決済み】非静的メソッドはターゲットを必要とする
-
[解決済み] EntityTypeにキーが定義されていないエラー
-
[解決済み】ファイルへの読み書きの際に共有違反のIOExceptionが発生する C#
-
[解決済み】aspNetCore 2.2.0 - AspNetCoreModuleV2 エラー
-
[解決済み】Unityでゲームオブジェクトのすべての子をループスルーして破壊する方法?
-
[解決済み】Microsoft.Extensions.LoggingからILoggerを解決することができない
-
[解決済み】Nullableオブジェクトは値を持たなければならない?