Инжекторный и динамический WithConstructor / WithMeta и RhinoMocks - PullRequest
0 голосов
/ 24 сентября 2011

В моем проекте у меня есть контейнер IoC, который инициализируется обычным способом с помощью ServiceModule.Когда я пишу модульные тесты, я хочу иметь возможность привязываться либо к StrictMock, DynamicMock, PartialMock или Stub.В прошлом у меня был FakeServiceModule, который связывал бы все с StrictMocks, но это очень ограничивало, и я хотел расширить это, чтобы позволить создать тип макета по своему выбору.

Для этого я создал следующее.

public class NinjectMocking
{
    public Type TypeToMock { get; set; }
    public MockType MockTypeToUse { get; set; }
    public IBindingWithOrOnSyntax<Type> BindingWithOrOnSyntax { get; set; }   
}

public enum MockType
{
    Stub,
    Strict,
    Dynamic,
    Partial
}

Идея состоит в том, что я бы инициализировал поддельный сервисный модуль следующим образом:

        foreach (var mockType in _mocks)
        {
            object ninjaMock;

            switch (mockType.MockTypeToUse)
            {
                case MockType.Strict:
                    {
                        ninjaMock = _mockRepository.StrictMock(mockType.TypeToMock);
                        break;
                    }
                case MockType.Dynamic:
                    {
                        ninjaMock = _mockRepository.DynamicMock(mockType.TypeToMock);
                        break;
                    }
                case MockType.Partial:
                    {
                        ninjaMock = _mockRepository.PartialMock(mockType.TypeToMock);
                        break;
                    }
                case MockType.Stub:
                    {
                        ninjaMock = _mockRepository.Stub(mockType.TypeToMock);
                        break;
                    }
                default:
                    {
                        ninjaMock = _mockRepository.StrictMock(mockType.TypeToMock);
                        break;
                    }
            }

            if (mockType.BindingWithOrOnSyntax == typeof(ConstructorArgument))
                Bind(mockType.TypeToMock).ToMethod(m => ninjaMock).w
                    .WithConstructorArgument(mockType.BindingWithOrOnSyntax);

            else
                Bind(mockType.TypeToMock).ToMethod(m => ninjaMock);
        }

После инициализации с помощьюсписок издевательств ...

       NinjectMocking ninjectMocking = new NinjectMocking();
        ninjectMocking.TypeToMock = typeToAdd;
        ninjectMocking.MockTypeToUse = MockType.Dynamic;

Это все отлично работает.Однако, и здесь возникает вопрос, некоторые из наших привязок нуждаются либо в .WithConstructorArgument, либо в .WithMetaData, как в

        Bind<ISomeRepository>().ToMethod(m => someRepository)
        .WithConstructorArgument("context", ctx => new TestDataContext());

, и, возможно, некоторые другие в будущем.Вот почему у меня есть свойство BindingWithOrOnSyntax в классе NinjectMocking.Поэтому мой новый инициализатор может выглядеть примерно так:

        NinjectMocking ninjectMocking = new NinjectMocking();
        ninjectMocking.TypeToMock = typeToAdd;
        ninjectMocking.MockTypeToUse = MockType.Dynamic;
        ninjectMocking.BindingWithOrOnSyntax.WithConstructorArgument("context", constructorArgument);

Проблема в том, что я не знаю, как заставить его использовать это в привязке.Я хотел бы сделать что-то вроде

Bind (mockType.TypeToMock) .ToMethod (m => ninjaMock). [WhatGoesHere]

Я не знаю, как это сделать сбит [WhatGoesHere] или как еще определить Bind, чтобы он использовал все, что я передаю, в свойстве BindingWithOrOnSyntax.Моя последняя отчаянная попытка состояла в том, чтобы попытаться заставить это сделать что-то вроде

            if (mockType.BindingWithOrOnSyntax == typeof(ConstructorArgument))
                Bind(mockType.TypeToMock).ToMethod(m => ninjaMock)
                    .WithConstructorArgument(mockType.BindingWithOrOnSyntax);

Но это, очевидно, не работает.

Любые указатели в правильном направлении, или даже если есть лучший способчтобы достичь этого, был бы очень признателен.

1 Ответ

2 голосов
/ 24 сентября 2011

Не используйте контейнер IOC во время модульного тестирования.Контейнер IOC должен использоваться во время выполнения для внедрения ваших зависимостей в ваши компоненты.Во время модульного тестирования вы создаете свои компоненты с поддельными / тупыми зависимостями.Если ваши компоненты разрешают зависимости непосредственно из контейнера IOC, вы не используете контейнер должным образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...