3

我正在为我的通用存储库层编写单元测试,但我遇到了一些问题DbEntityEntry

我的更新方法如下。

  public virtual void Update(TEntity entityToUpdate) {
            var entity = dbSet.Find(context.Entry<ITrackedEntity>(entityToUpdate).Entity.Id);
            context.Entry(entity).CurrentValues.SetValues(entityToUpdate);
        }

如您所见,context.Entry<TEntity>(TEntity entity)方法由调用者调用。因此,在单元测试时,此代码会引发空异常。

我曾尝试模拟context.Entry方法,但我不能,因为我无法提供返回值。

我目前的测试方法如下

[Fact]
        public void UpdateTest() {
            AssetType _sample1 = new AssetType() {
                AssetTypeID = 1,
                IsContainer = true,
                Name = "Sample 1"
            };

            IDbSet<AssetType> assetTypeDbSet = new FakeDbSet<AssetType>(_sample1);

            Mock<IDbContext> mockContext = new Mock<IDbContext>();
            mockContext.Setup(pc => pc.Set<AssetType>()).Returns(assetTypeDbSet);
            _sample1.Name = "Sample 1.1";

            var dbEntity = mockContext.Object.Entry<ITrackedEntity>(_sample1);
            mockContext.Setup(p => p.Entry<ITrackedEntity>(It.IsAny<AssetType>())).Returns(dbEntity);
            using(GenericRepository<AssetType> repo = new GenericRepository<AssetType>(mockContext.Object)) {                
                repo.Update(_sample1);
                var result = repo.GetAll(0, 0);
                Assert.Equal(1, result.Count);
                var singleResult = repo.GetByID(1);
                Assert.Equal(_sample1.Name, singleResult.Name);
            }
        }

我试图通过在测试中DbEntityEntry调用context.Entry<>()方法来获得价值,但那也返回null了。这个类也不能用new操作符初始化。所以我卡住了。。

4

1 回答 1

1

对这段代码进行单元测试有什么意义?你伪造Find方法,然后你伪造DbEntityEntry,将没有真正的逻辑来测试。

无论如何,EF 代码通常是不可单元测试的。这就是人们相信存储库会帮助他们的原因之一,因为他们在测试上层时会模拟/伪造他们的存储库。然后使用集成测试对存储库进行测试,以确保 EF 和数据库中的所有内容都按预期工作。

你不会DbEntityEntry用 Moq 造假。也许使用 TypeMock Isolator 或 MS Fakes,您将能够做更多事情,但在您的示例代码中不需要它。

于 2013-04-16T18:56:53.080 回答