Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
antoniomfc opened this issue Nov 20, 2019 · 8 comments
Labels

Comments

@antoniomfc
Copy link

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 :)

@stakx
Copy link
Contributor

stakx commented Nov 20, 2019

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

@dash-bhavinbhesaniya
Copy link

@stakx Thank you so much, You really saved my day.

@Adnan-Prince
Copy link

@stakx thank you so much this error takes my two days

@yogeshwarkkokulwar
Copy link

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

how to make virtual

@dash-bhavinbhesaniya
Copy link

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

how to make virtual

Just you need to declare virtual in your entity class. Like

public virtual Department? department { get; set; }

Department is my entity table name.

@dash-bhavinbhesaniya
Copy link

using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

namespace MyDemo.Database.DataContext
{
public class MyDemoDbContext : IdentityDbContext<MyDemoUser, MyDemoUserRoles, long, UserClaim, UserRoles, UserLogin, RoleClaim, UserToken>
{
public MyDemoDbContext()
{

    }
    public MyDemoDbContext(DbContextOptions<MyDemoDbContext> options) : base(options)
    {

    }
    protected override void OnConfiguring(DbContextOptionsBuilder builder)
    {
        builder.EnableSensitiveDataLogging();
    }
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
       
        modelBuilder.Entity<Hospital>(entity =>
        {
            entity.ToTable("Hospital");
            entity.Property(e => e.Id).HasDefaultValueSql("(newid())");
        });

    }
    public virtual DbSet<Hospital> Hospital { get; set; } = null!;
   
}

}

For your test controller :

using AutoMapper;
using Moq;
using MyDemo.Database.DataContext;

namespace MyDemo.TestCases.Service.Hospital
{
public class HospitalControllerUnitTest
{
private Mock _mockMyDemoDbContext;
private Mock _mokeIHospitalService;
[SetUp]
public void SetUp()
{
_mockMyDemoDbContext = new Mock();
_mokeIHospitalService = new Mock();
}

    [Test]
    public void Create_Should_Return_True()
    {
        // Arrange
        AddressModel addressModel = new AddressModel()
        {
            DisplayAddress = "12300 Bermuda Rd, Henderson, NV 89044, USA"
        };
        HospitalModel hospitalModel = new HospitalModel()
        {
            Name = "Covidien",
            IsActive = true,
            DisplayAddress = "12300 Bermuda Rd, Henderson, NV 89044, USA",
            Address = addressModel
        };

        var hospitalList = new List<Database.Entities.Hospital>
                            {
                                new Database.Entities.Hospital {
                                            Id=Guid.Parse("0D9CCAA6-5F21-4F31-AA8B-08EFD62E3CFD"),
                                            Name = "Houston Methodist Hospital"},
                                new Database.Entities.Hospital {
                                             Id=Guid.Parse("702BE63D-F23E-4F47-932E-171611C5AE84"),
                                             Name = "Medical Center of Central Georgia"
                                              },
                            };
       
        // Arrange
        var mockHospitalDbSet = DbContextMockHelper.GetQueryableMockDbSet<Database.Entities.Hospital>(hospitalList);
        _mockMyDemoDbContext.Setup(c => c.Hospital).Returns(mockHospitalDbSet);
      
        // Act
        HospitalService hospitalService = new HospitalService(_mockMyDemoDbContext.Object);
        var hospitalServiceResponse = hospitalService.Create(hospitalModel);
    }
}

}

@Mohammed-Hakeeb-Javid this way working for me. what is Persistent here you have inherited? Try this kind of code and let me know if it will not work will find a way for you.

@Mohammed-Hakeeb-Javid
Copy link

Mohammed-Hakeeb-Javid commented Aug 21, 2023

Hi @BhavinVoingTech Thanks for replay here problem is our new project pattern they are using in context class like this
public MyDemoDbContext(IConfiguration configuration, IAuthService auth)
: base(CreateOptions(configuration.GetConnectionString("MyDemoDbContext")))
{

}

instead of
public MyDemoDbContext(DbContextOptions options) : base(options)
{

}

so how to pass there iconfigure and iauth with connection string? tried various method not working!

@Mohammed-Hakeeb-Javid
Copy link

also was writing for repository test so when we were passig moq.object to repo giving this error
System.ArgumentException : Can not instantiate proxy of class: Repository.API.Infrastructure.DataBase.MyDemoDbContext.
Could not find a constructor that would match given arguments:

@devlooped devlooped locked and limited conversation to collaborators Sep 5, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

6 participants