Каков наилучший способ сделать мой статический класс тестируемым? - PullRequest
1 голос
/ 25 августа 2011

В моем приложении asp.net у меня есть следующий статический класс для обработки строк запроса в моем приложении, от которых зависят некоторые классы:

public static class QueryStringUtil
{
    public static int? GetStoreId()
    {
        return GetId(QueryStrings.StoreId);
    }

    public static string GetItemCode()
    {
        return Get(QueryStrings.ItemCode);
    }       

    private static string Get(string queryStringName)
    {
        return HttpContext.Current.Request.QueryString[queryStringName];
    }

    private static int? GetId(string queryStringName)
    {
        var queryString = Get(queryStringName);
        int queryStringParsed;
        return int.TryParse(queryString, out queryStringParsed) ? (int?)queryStringParsed : null;
    }
}

Как лучше всего сделать этот класс тестируемым?

Один из известных мне способов состоит в том, чтобы реорганизовать это и создать вместо этого класс экземпляра синглтона с его интерфейсом и позволить зависимым классам принять интерфейс моего синглтон-класса. Не уверен, что это будет моим лучшим вариантом.

Другой вариант - сделать мой класс обычным классом с интерфейсом, а затем создать одноэлементный класс ServiceLocator, ответственный за хранение экземпляров всех классов, которые должны вести себя как одиночный объект, такой как мой QueryStringUtil, и затем разрешить моему зависимому классу принимать интерфейс на мой IQueryStringUtil.

Третий вариант, о котором я могу подумать, - это не использовать мой класс локатора пользовательских служб, а вместо этого использовать контейнер IoC, например Microsoft Unity, а затем сохранить экземпляр singleton в файле конфигурации контейнера IoC и внедрить его в мои зависимые классы.

Пожалуйста, сообщите ваш лучший вариант и почему.

Большое спасибо,

Ответы [ 3 ]

2 голосов
/ 25 августа 2011

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

0 голосов
/ 29 августа 2011

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

Когда вы тестируете эти классы, может быть полезным иметь интерфейс для QueryStringUtil ...?

Однако, чтобы попытаться дать более общий ответ, любой тип синглтона является обязательным для тестирования (это такая форма глобального состояния, как глобальная переменная, файл или база данных). Общий ответ на эту проблему - использовать Инъекция зависимостей (я думаю, что имя более точное и понятное, чем «Инверсия контроля», что на самом деле означает несколько разных вещей в зависимости от разных людей). Я не знаком с Asp.net, поэтому не могу сказать, какую библиотеку использовать, но у вас не возникнет проблем с ее поиском.

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

0 голосов
/ 25 августа 2011

Я предпочитаю интерфейс и обычный класс в контейнере IoC.Вы можете создавать экземпляры и управлять значениями, отправляемыми вашим протестированным классам / методам, с помощью любой моделируемой среды.В противном случае вы будете вынуждены использовать некоторую изолированную среду, такую ​​как TypeMock или Moles, для имитации значений из ваших статических методов.

...