问题描述
我正在为通用存储库层编写单元测试,但是DbEntityEntry
存在一些问题.
I am writing unit tests for my Generic Repository layer but i have some problems with 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)
方法.因此,当进行单元测试时,此代码将引发null异常.
As you can see, context.Entry<TEntity>(TEntity entity)
method is invoked by caller. So while unit tests this code throws null exception.
我曾尝试模拟context.Entry
方法,但由于无法提供返回值而无法执行.
I had tried to mock context.Entry
method but i couldn't because i couldn't provide return value.
我当前的测试方法如下
[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);
}
}
我试图通过在测试中调用context.Entry<>()
方法来获取DbEntityEntry
值,但是那也返回了null
.同样,不能使用new
运算符来初始化此类.所以我卡住了..
I tried to get DbEntityEntry
value by calling context.Entry<>()
method at test but that wa returned null
, too.Also this class cannot be iniated with new
operator. So i stucked..
推荐答案
单元测试此代码的重点是什么?伪造Find
方法,然后伪造DbEntityEntry
,将没有真正的逻辑可以测试.
And what is the point of unit testing this code? You fake the Find
method, then you fake DbEntityEntry
and there will be no real logic to test.
任何情况下,EF代码通常都不能进行单元测试.这就是为什么人们认为存储库会帮助他们的原因之一,因为他们在测试上层时会嘲笑/伪造存储库.然后,通过集成测试对存储库进行测试,以确保EF和数据库中的所有内容均按预期工作.
Anyway EF code is not unit testable in general. That is one reason why people believe that repository will help them because they mock / fake their repository when testing upper layer. Repository is then tested with integration tests to make sure that everything in EF and database works as expected.
您不会用Moq伪造DbEntityEntry
.也许使用TypeMock Isolator或MS Fakes,您将可以执行更多操作,但示例代码中并不需要这样做.
You will not fake DbEntityEntry
with Moq. Maybe with TypeMock Isolator or MS Fakes you will be able to do more but it is not needed in your sample code.
这篇关于模拟DbEntityEntry的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!