Тестирование moq: System.NotSupportedException: неподдерживаемое выражение: c = ›c.Prices

У меня проблема с проверкой моего контекста.

Мое приложение работает в .NET Core 2.2, и я установил EFCore v2.2.6.

Когда я запускаю свой тест, я получаю такую ​​ошибку:

System.NotSupportedException: неподдерживаемое выражение: c => c.Prices Непереопределяемые элементы (здесь: MyContext.get_Prices) не могут использоваться в выражениях настройки / проверки.

Это мой класс контекста:

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

Это мой репозиторий:

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();

    }
}

Мой ценовой класс:

    [Table("Price")]
    public class Price
    {

        public string CustomerAccount { get; set; }
        public string ItemId { get; set; }
        public double Amount { get; set; }
        [NotMapped]
        public int Id { get; set; }
        [NotMapped]
        public string ItemInternalId { get; set; }
        [NotMapped]
        public DateTime ModifiedDateTime { get; set; }
    }

Мой тест:

    [Fact]
    public async Task Test1Async()
    {


        IQueryable<Price> prices = new List<Price>
        {
                new Price
                {
                    Amount = 39.71,
                    CustomerAccount = "010324",
                    ItemId = "10103001",
                    Id = 1,
                    ItemInternalId = "test",
                    ModifiedDateTime = new System.DateTime()
                },
                new Price
                {
                    Amount = 57.09,
                    CustomerAccount = "010324",
                    ItemId = "10103001",
                    Id = 2,
                    ItemInternalId = "test2",
                    ModifiedDateTime = new System.DateTime()
                }

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

Может кто-нибудь мне помочь?

Спасибо :)


person Antonio Fernández    schedule 20.11.2019    source источник
comment
Нет необходимости издеваться над контекстом при использовании в памяти.   -  person Nkosi    schedule 20.11.2019


Ответы (1)


Нет необходимости издеваться над контекстом при использовании в памяти.

[Fact]
public async Task Test1Async() {
    //Arrange
    var prices = new List<Price> {
        new Price {
            Amount = 39.71,
            CustomerAccount = "010324",
            ItemId = "10103001",
            Id = 1,
            ItemInternalId = "test",
            ModifiedDateTime = new System.DateTime()
        },
        new Price
        {
            Amount = 57.09,
            CustomerAccount = "010324",
            ItemId = "10103001",
            Id = 2,
            ItemInternalId = "test2",
            ModifiedDateTime = new System.DateTime()
        }
    };

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

    var context = new MyContext(options);
    //populate
    foreach(var price in prices) {
        context.Prices.Add(price);
    }
    await context.SaveChangesAsync();

    var repository = new PriceRepository(mockContext.Object);

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

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

    //Assert
    Assert.Single(result);
}
person Nkosi    schedule 20.11.2019
comment
Это работает! Спасибо. Если я не хочу использовать UseInMemory, как я могу это сделать? - person Antonio Fernández; 20.11.2019