Question

I am writing unit tests for my Generic Repository layer but i have some problems with DbEntityEntry.

My Update method is like below.

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

As you can see, context.Entry<TEntity>(TEntity entity) method is invoked by caller. So while unit tests this code throws null exception.

I had tried to mock context.Entry method but i couldn't because i couldn't provide return value.

My current test method is below

[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);
            }
        }

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..

Was it helpful?

Solution

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.

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.

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top