Moq4: System.NotSupportedException : Unsupported expression: c => c.Prices. Non-overridable members (here: TekaSelectContext.get_Prices) may not be used in setup / verification expressions.

Created on 20 Nov 2019  路  1Comment  路  Source: moq/moq4

Hi everyone,

I have a problem with testing my Context.

My app is running in .NET Core 2.2 and I've installed EFCore v2.2.6.

When I launch my test I get this error:

System.NotSupportedException : Unsupported expression: c => c.Prices
Non-overridable members (here: MyContext.get_Prices) may not be used in setup / verification expressions.

This is my context class:

using MyProject.Model;
using Microsoft.EntityFrameworkCore;

namespace MyProject.Persistence
{
    public class MyContext : DbContext
    {
        public MyContext(DbContextOptions<MyContext> options) : base(options) {}
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Price>()
                .HasKey(p => new { p.CustomerAccount, p.ItemId, p.Amount });

        }

        public DbSet<Price> Prices { get; set; }
    }
}

This is My repository:

using MyProject.Model;
using MyProject.Persistence;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace MyProject.Repository
{
    public class PriceRepository : IPriceRepository
    {
        private readonly MyContext _myContext;


        public PriceRepository(MyContext myContext)
        {
            _myContext = myContext;
        }

        public async Task<List<Price>> GetPricesAsync(List<string> items, string customerAccount)
                => await _myContext.Prices.Where(price => price.CustomerAccount == customerAccount && items.Contains(price.ItemId)).ToListAsync();

    }
}

and this is my test:

    [Fact]
    public async Task Test1Async()
    {


        IQueryable<Price> prices = new List<Price>
        {
            new Price
            {
                Amount = 39.71,
                CustomerAccount = "010324",
                ItemId = "10103001"
            },
            new Price
            {
                Amount = 57.09,
                CustomerAccount = "010324",
                ItemId = "10103001"
            }

        }.AsQueryable();

        var mockSet = new Mock<DbSet<Price>>();

        var options = new DbContextOptionsBuilder<MyContext>()
                    .UseInMemoryDatabase(databaseName: "FekaConnectionString")
                    .Options;

        mockSet.As<IQueryable<Price>>().Setup(m => m.Provider).Returns(prices.Provider);
        mockSet.As<IQueryable<Price>>().Setup(m => m.Expression).Returns(prices.Expression);
        mockSet.As<IQueryable<Price>>().Setup(m => m.ElementType).Returns(prices.ElementType);
        mockSet.As<IQueryable<Price>>().Setup(m => m.GetEnumerator()).Returns(prices.GetEnumerator());

        var mockContext = new Mock<MyContext>(options);

        mockContext.Setup(c => c.Prices).Returns(mockSet.Object);

        var repository = new PriceRepository(mockContext.Object);

        var list = new List<string>
        {
            "10103001"
        };

        var result = await repository.GetPricesAsync(list, "010324");

        Assert.Single(result);
    }

Can anyone help me?

Thanks :)

question

Most helpful comment

Try making Prices virtual. Moq cannot mock non-virtual type members.

>All comments

Try making Prices virtual. Moq cannot mock non-virtual type members.

Was this page helpful?
0 / 5 - 0 ratings