1
votes

I've managed to Mock an Entity Framework dbcontext and dbset to allow for unit testing querying functions against a repository component.

I've been unable to perform a successful test against an a method using Entity Frameworks' AddOrUpdate() method. The error received is:

"Unable to call public, instance method AddOrUpdate on derived IDbSet type 'Castle.Proxies.DbSet`1Proxy'. Method not found."

Is it at all possible to test this?

    private IRepository _Sut;
    private Mock<DbSet<JobListing>> _DbSet;
    private Mock<RecruitmentDb> _DbContext;

    [SetUp]
    public void Setup()
    {
        _DbContext = new Mock<RecruitmentDb>();

        var JobsData = GenerateJobs().AsQueryable();

        _DbSet = new Mock<DbSet<JobListing>>();
        _DbSet.As<IQueryable<JobListing>>().Setup(x => x.Provider).Returns(JobsData.Provider);
        _DbSet.As<IQueryable<JobListing>>().Setup(x => x.Expression).Returns(JobsData.Expression);
        _DbSet.As<IQueryable<JobListing>>().Setup(x => x.ElementType).Returns(JobsData.ElementType);
        _DbSet.As<IQueryable<JobListing>>().Setup(x => x.GetEnumerator()).Returns(JobsData.GetEnumerator());

        _DbContext.Setup(x => x.JobListings).Returns(_DbSet.Object);
        _Sut = new JobListingRepository(_DbContext.Object);
    }

    [Test]
    public void Update_ChangedTitleProperty_UpdatedDetails()
    {
        var Actual = GenerateJobs().First();
        var OriginalJob = Actual;
        Actual.Title = "Newly Changed Title";
        _Sut.Update(Actual);

        Actual.Title.Should().NotBe(OriginalJob.Title);
        Actual.Id.Should().Be(OriginalJob.Id);
    }

    private List<JobListing> GenerateJobs()
    {
        return new List<JobListing>
        {
            new JobListing{ Id = 1,
            Title = "Software Developer",
            ShortDescription = "This is the short description",
            FullDescription = "This is the long description",
            Applicants = new List<Applicant>(),
            ClosingDate = DateTime.Now.AddMonths(5).Date},

            new JobListing{
            Id = 2,
            Title = "Head Chef",
            ShortDescription = "This is the short description",
            FullDescription = "This is the long description",
            Applicants = new List<Applicant>(),
            ClosingDate = DateTime.Now.AddMonths(2).Date
            },

            new JobListing
        {
            Id = 3,
            Title = "Chief Minister",
            ShortDescription = "This is the short description",
            FullDescription = "This is the long description",
            Applicants = new List<Applicant>(),
            ClosingDate = DateTime.Now.AddMonths(2).Date
        }
        };
    }
1
I don't see AddOrUpdate in your code.Gert Arnold
But it's probably related to AddOrUpdate being an extension method.Gert Arnold
AddOrUpdate is used within the concrete JobListingRepository. How do you perform the test with an extension method?ManxJason
If that is the question, this would be a duplicate.Gert Arnold

1 Answers

1
votes

The issue is because AddOrUpdate is an extension method. I overcame this issue by designing a wrapper. You can mock/stub the IAddOrUpdateHelper interface instead.

    public class AddOrUpdateHelper : IAddOrUpdateHelper
    {

        public void AddOrUpdateEntity<TEntity>(DataContext db, params TEntity[] entities) where TEntity : class
        {
            db.Set<TEntity>().AddOrUpdate(entities);
        }
    }

    public interface IAddOrUpdateHelper
    {
        void AddOrUpdateEntity<TEntity>(DataContext db, params TEntity[] entities) where TEntity : class;
    }