Замените ядро ​​EF DbContext - как его использовать? - PullRequest
0 голосов
/ 24 апреля 2020

Я пытаюсь создать модульный тест для класса, который использует мой EF Core DbContext:

public class MyContext : DbContext
{
    public MyContext(DbContextOptions<MyContext> options) : base(options)
    {
    }

    public DbSet<SomeTable> SomeTables { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        ...
    }
}

класс, который использует этот контекст, прост:

public class MyClass
{
    public MyClass(MyContext db)
    {
    }
}

поэтому, когда я пытаюсь создать

var fakeContext = Substitute.For<MyContext>();

, что заканчивается ошибкой:

Castle.DynamicProxy.InvalidProxyConstructorArgumentsException : Can not instantiate proxy of class: MyContext.
Could not find a parameterless constructor.

, которая вызывается конструктором base(options). Итак, подход net заключался в расширении кода:

var dbContextOptions = Substitute.For<DbContextOptions<MyContext>>();

dbContextOptions.ContextType.Returns(typeof(MyContext));

var dbContextOptionsExtension = Substitute.For<IEnumerable<IDbContextOptionsExtension>>();
dbContextOptions.Extensions.Returns(dbContextOptionsExtension);

var myFakeContext = Substitute.For<MyContext>(dbContextOptions);

, но он генерирует больше ошибок. Итак, как это исправить?

Ответы [ 2 ]

2 голосов
/ 24 апреля 2020

Вы не уточнили дополнительные ошибки, поэтому я не могу дать конкретный c ответ, однако попытка правильно смоделировать DbContext затруднена. IMO есть два варианта.

1) Используйте провайдера оперативной памяти Microsoft .

2) Если вы хотите использовать фиктивный DbContext с помощью NSubstitute, используйте пре -существующая библиотека, которая делает издевательства за вас. Есть несколько таких, как EntityFrameworkCore.Testing.NSubstitute (отказ от ответственности - я автор).

Поставщик в памяти не является полной реализацией, он не может выполнять реляционные операций и существует множество операций LINQ, которые он не поддерживает, поэтому в зависимости от ваших вариантов использования последний может быть лучшим решением.

Если у вас есть конкретный c error / use case в виду pop pop и я смогу дать лучший ответ.

0 голосов
/ 24 апреля 2020

Хорошо, я использовал провайдера InMemory:

var options = new DbContextOptionsBuilder<AgreementContext>()
                .UseInMemoryDatabase("fakeDb")
                .Options;

var agreementContext = Substitute.For<MyContext>(options);
...