我正在使用 .NET 4.5、EF6,并且正在尝试使用 JustMock 2.0 来测试我的应用程序。
我试图通过模拟我的DbContext子类来模拟我的数据库:CoreDataRepositoryContext。
为此,我需要通过返回一个假数据集合来模拟DbContext的成员SaveChanges和我的类CoreDataRepositoryContext的每个DbSet类型属性。我还需要模拟以下DbSet的成员:
- 添加
- 消除
- 可查询的
我需要为CoreDataRepositoryContext和DbSet的所有实例模拟它
例如,我在数据库中有Order类型的实体(表Orders)我做了以下模拟表Orders:
// FakeOrders is a list of orders (List<Order>)
var mockedContext = Mock.Create<CoreDataRepositoryContext>();
// Mock works
Mock.Arrange(() => mockedContext.SaveChanges()).IgnoreInstance().DoNothing();
// Mock works
Mock.Arrange(() => mockedContext.Orders).IgnoreInstance().ReturnsCollection(FakeOrders);
// Mock works
Mock.Arrange(() => mockedContext.Orders.Add(Arg.IsAny<Order>())).IgnoreInstance().DoInstead((Order o) => FakeOrders.Add(o));
// Mock works
Mock.Arrange(() => mockedContext.Orders.Remove(Arg.IsAny<Order>())).IgnoreInstance().DoInstead((Order o) => FakeOrders.Remove(o));
// Mock DOES NOT work !
Mock.Arrange(() => mockedContext.Orders.AsQueryable()).IgnoreInstance().Returns(() => FakeOrders.AsQueryable());
mockedContext.Orders属于DbSet< Order >类型,而 FakeOrders 属于List< Order >类型。这两个类都实现了接口IEnumerable< Order >。
模拟Add和Remove成员效果很好,因为这两种方法都没有在接口IEnumerable< T >中声明。
另一方面,AsQueryable在此接口中声明并由Queryable定义。因此,当我使用IgnoreInstance模拟成员时,从实现IEnumerable< T >的任何类的实例调用AsQueryable 会启动一个永无止境的循环。因为IEnumerable< Order >.AsQueryable被FakeOrders.AsQueryable嘲笑,而 FakeOrders.AsQueryable被... FakeOrders.AsQueryable ...无限循环...
var query = mockedContext.Orders.AsQueryable(); // Infinite loop
query = FakeOrders.AsQueryable(); // Infinite loop
query = new List<Order>().AsQueryable(); // Infinite loop
我怎样才能只模拟DbSet< Order >.AsQueryable,而不使用IgnoreInstance 模拟IEnumerable< Order > .AsQueryable?
感谢您的帮助 :)