Как настроить модульные тесты с контейнером IoC в ASP.NET? - PullRequest
1 голос
/ 29 сентября 2011

Я настроил Unity в своем приложении ASP.NET, и конфигурация загружается при получении первого запроса в Application_BeginRequest.затем контейнер Unity сохраняется в Global.ascx как свойство, так что мой другой класс может получить к нему доступ:

public static IUnityContainer ContainerHolder { get; set; }

IUnityContainer IContainerAccessor.Container
{
    get { return ContainerHolder; }
}

ContainerHolder, содержит экземпляр контейнера во всем приложении, а свойство Container разрешает доступ к этому свойству в каждомсеанс.

Затем у меня есть класс UnityLocator, который позволяет мне получить доступ к этому свойству через приложение:

public static class UnityLocator
    {        
        private static IUnityContainer Container
        {
            get
            {
                return ((IContainerAccessor)HttpContext.Current.ApplicationInstance).Container;
            }
        }
    }

Все отлично работает!

У меня также есть метод для доступаэкземпляр из Unity:

UnityLocator.GetInstance<IThemeManager>();

    protected Repository(ICustomCacheManager customCacheManager)
    {
        this.Cache = customCacheManager;
    }

    protected Repository()
        : this(UnityLocator.GetInstance<ICustomCacheManager>())
    {

    }

это использовалось в моем приложении, чтобы я мог извлечь существующий экземпляр из Unity, чтобы я мог внедрить его в другие классы.Например, мое представление (страница asp.net) внедряет это в свой класс Presenter в качестве зависимости.

Теперь я хотел бы настроить для запуска мои модульные тесты.

Как я могу это сделатьтот?!Очевидно, что global.ascx там не существует, поэтому я подумал, что мне следует создать класс BaseTest и позволить всем моим тестам наследовать его.затем в конструкторе этого класса BaseTest я создаю свои экземпляры.Это правильный способ сделать это?

Как настроить модульные тесты с Unity сейчас?

Спасибо

ОБНОВЛЕНИЕ: добавлен UnityLocator.GetInstance.

Ответы [ 3 ]

5 голосов
/ 29 сентября 2011

Вам не нужно беспокоиться о доступе к вашему контейнеру IoC. Это нарушение юнит-тестов.

Модульные тесты: вам не нужно беспокоиться о какой-либо конкретной реализации или зависимости (кроме тестируемого класса).

Для меня наличие IoC в глобальном масштабе - плохой выбор дизайна. Вы должны вводить свои зависимости через свойства или конструкторы.

1 голос
/ 29 сентября 2011

На своей странице попробуйте сделать что-то вроде этого:

public class DepartmentReportPage : Page
{
    private readonly DepartmentReportPresenter _presenter;

    public DepartmentReportPage()
    {
        this._presenter =
            UnityLocator.GetInstance<DepartmentReportPresenter>();

        this._presenter.View = this;
    }
}
1 голос
/ 29 сентября 2011

Вероятно, использование глобального класса приложения для хранения локатора службы не было хорошей идеей. Почему вы не используете встроенный класс ServiceLocator? Он доступен в любом месте кода и не зависит от глобального приложения / HttpContext.

Является ли использование контейнера в модульных тестах другой историей. Лично я не против, если вы положите в контейнер реализации-заглушки ваших служб.

Редактировать: способ настройки контейнера с помощью ServiceLocator:

    private void ConfigureUnity()
    {
        UnityServiceLocator locator = new UnityServiceLocator( ConfigureUnityContainer() );
        ServiceLocator.SetLocatorProvider( () => locator );
    }

    private IUnityContainer ConfigureUnityContainer()
    {
        IUnityContainer container = new UnityContainer();

        // this loads container's configuration, comment or uncomment
        container.LoadConfiguration();

        return container;
    }

Затем вы можете получить доступ к контейнеру из локатора, например:

var container = ServiceLocator.Current.GetInstance<IUnityContainer>();
...