如何进行单元测试.包含用于实体框架的急切加载



我有一个方法,它的目的是从DbSet中获取一个实体,相关数据已经被急切地加载到其中(它的逻辑中有一个.Includes中的序列(。相关字段是virtual IEnumerable,并且是延迟加载的。

现在我想对这个方法进行单元测试,以检查它是否加载了我需要的所有数据。我不知道如何处理它,我可以创建一个预期的实体并用数据填充它,但简单地模仿IDbSet(我使用的是Moq(是行不通的——如果我从测试的方法中删除所有.Includes,它仍然会返回所有相关的实体,这不是它在实际数据库中的"实时"行为(实体不会被加载,方法的契约也不会履行(。

那么,我如何模拟IDbSet,使其在没有显式.Includes的情况下真正延迟加载呢?或者也许我做得完全错了,还有其他方法可以测试这种方法?

测试服务/存储库是否包含相关实体将是一个集成测试场景,而不是单元测试。像这样的集成测试看起来像一个单元测试,是用NUnit/MTest编写的,但它与单元测试是分开的,这样它就不会与普通的单元测试套件一起运行,因为这些测试运行起来可能相当耗时。

例如。

MyParentEntity entity = null;
using (var dbContext = new MyDbContext(connectionString))
{
var myRepository = new MyRepository(dbContext);
entity = myRepository.GetEntityById(1);
} // leave the scope of the DbContext.
// example asserts...
Assert.IsNotNull(entity.Relative, "Relative was not eager loaded."); // Null or EF Exception if proxy attempts to lazy-load.
Assert.IsTrue(entity.Children.Count == 3, "Children were not eager loaded.");

这意味着已知的数据状态,因此集成测试通常使用内存中的数据库,这些数据库可以相当快速地填充,或者设置为在测试设备设置中恢复已知数据状态的数据库备份。

如果你不想关闭上下文,你可以做一些类似的事情

_context.Entry(retreivedEntry).Reference(e => e.Field).IsLoaded
_context.Entry(retreivedEntry).Collection(e => e.CollectionField).IsLoaded

最新更新