Как макетировать контекст на основе интерфейса при использовании Ninject? - PullRequest
0 голосов
/ 27 апреля 2018

У меня есть нормальный контекст Entity Framework, который выглядит следующим образом:

public class LikvidoWebsitesApiContext : IdentityDbContext<ApplicationUser>, ILikvidoWebsitesApiContext
{   
   // code
}

Я сделал интерфейс с моим DBSets.

В моем обычном решении я настроил его на Ninject следующим образом:

kernel.Bind<ILikvidoWebsitesApiContext>().To<LikvidoWebsitesApiContext>().InRequestScope();

Я использую контекст в своих службах, добавляя ILikvidoWebsitesApiContext внутри конструктора, и затем я могу использовать базу данных.

Мой вопрос: как мне настроить это в модульном тесте?

Я пытался сделать следующее:

kernel.Bind(typeof(ILikvidoWebsitesApiContext))
            .To(typeof(Mock<LikvidoWebsitesApiContext>))
            .Register(true);

(с использованием Moq framework)

Однако это дает:

System.InvalidCastException: 'Невозможно привести объект типа' Moq.Mock`1 [Likvido.Domain.Services.Data.LikvidoWebsitesApiContext] ', чтобы ввести' Likvido.Domain.Services.Data.ILikvidoWebsitesApiContext '.'

Что имеет смысл, но я не совсем уверен, как это исправить?

1 Ответ

0 голосов
/ 28 апреля 2018

После быстрого просмотра вики Ninject я наткнулся

Поставщики, фабричные методы и контекст активации

Где они показывают, как использовать Provider для создания экземпляров.

Следуя предложению в вики, было рекомендовано расширить Provider<T>, что включает строгую типизацию.

public MoqContextProvider : Provider<ILikvidoWebsitesApiContext> {
    protected override ILikvidoWebsitesApiContext CreateInstance(IContext context) {
        var mock = new Mock<ILikvidoWebsitesApiContext>();

        // Set up of mock members

        return mock.Object;
    }
}

И тогда это просто вопрос подключения к контейнеру

kernel.Bind<ILikvidoWebsitesApiContext>().ToProvider(new MoqContextProvider());

Было также предложено использовать Заводские методы

Более легкая альтернатива написанию IProvider реализаций - это привязка службы к методу делегата.

kernal.Bind<ILikvidoWebsitesApiContext>()
    .ToMethod(context => {
        var mock = new Mock<ILikvidoWebsitesApiContext>();

        // Set up of mock members

        return mock.Object;    
    });

Предоставленное Func будет привязано к типу службы для отложенной привязки и будет вызвано позже, когда потребуется новый экземпляр службы (т. Е. ILikvidoWebsitesApiContext).

Помните, что при использовании Moq вам нужно настроить желаемое поведение макетов.

...