Правильный способ модульного тестирования приватных переменных - PullRequest
0 голосов
/ 07 сентября 2010

У меня есть следующий метод:

private string _google = @"http://www.google.com";

public ConnectionStatus CheckCommunicationLink()
{
    //Test if we can get to Google (A happy website that should always be there).
    Uri googleURI = new Uri(_google);
    if (!IsUrlReachable(googleURI, mGoogleTestString))
    {
        //The internet is not reachable.  No connection is available.
        return ConnectionStatus.NotConnected;
    }

    return ConnectionStatus.Connected;
}

Вопрос в том, как заставить его не пытаться подключиться к Google (таким образом избегая зависимости от интернета).

Самый простой способ - взять _google и изменить его так, чтобы он указывал на что-то локальное для машины. Но для этого мне нужно сделать _google public. Я бы предпочел не делать этого, потому что приложение не должно изменять _google.

Я мог бы сделать _google параметром для перегруженной версии метода (или конструктора объекта). Но это также открывает интерфейс, который я никогда не хочу использовать в приложении.

Другой вариант - сделать _google internal. Но для приложения internal совпадает с public. Таким образом, в то время как другие не могут видеть _google, интерфейс приложения все еще предоставляет его.

Есть ли лучший способ? Если это так, пожалуйста, укажите это.

(Также, пожалуйста, не выбирайте мой пример, если он действительно не помогает найти решение. Я прошу идеи по таким общим сценариям, а не обязательно по этому точному примеру.)

Ответы [ 4 ]

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

Выполните рефакторинг вашего кода, чтобы он зависел от ICommunicationChecker:

public interface ICommunicationChecker
{
    ConnectionStatus GetConnectionStatus();
}

Тогда ваши тесты могут смоделировать этот интерфейс, делая детали реализации ненужными.

public class CommunicationChecker : ICommunicationChecker
{
    private string _google = @"http://www.google.com";

    public ConnectionStatus GetConnectionStatus()
    {
        //Test if we can get to Google (A happy website that should always be there).
        Uri googleURI = new Uri(_google);
        if (!IsUrlReachable(googleURI, mGoogleTestString))
        {
            //The internet is not reachable.  No connection is available.
            return ConnectionStatus.NotConnected;
        }

        return ConnectionStatus.Connected;
    }
}
0 голосов
/ 07 сентября 2010

Некоторые опции:

  • make _google загрузить из внешней конфигурации (возможно, предоставив www.google.com в качестве значения по умолчанию) и предоставить специальную конфигурацию для модульных тестов;
  • поместите класс модульного теста в класс, содержащий метод CheckCommunicationLink.

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

0 голосов
/ 08 сентября 2010

В целях модульного тестирования вы должны смоделировать любое http-соединение, которое вы используете в своем классе (которое скрыто в методе IsUrlReachable). Таким образом, вы можете проверить, что ваш код действительно пытается подключиться к Google без фактического подключения. Пожалуйста, вставьте IsUrlReachable метод, если вам нужна дополнительная помощь с насмешкой.

Если вышеприведенное решение не является вариантом, вы можете рассмотреть возможность использования локального тестового http-сервера и:

  1. Настройка URL-адреса для настройки, чтобы вы могли указывать на локальный адрес
  2. (это противно). Используйте рефлексию, чтобы изменить _google перед тестами
  3. (большинство пуристов здесь не согласятся). Вы можете создать перегрузку, принимающую параметр, и использовать ее для тестирования (поэтому вы тестируете только CheckCommunicationLink(string url) метод

код для (3):

private string _google = @"http://www.google.com";

public ConnectionStatus CheckCommunicationLink()
{
    return CheckCommunicationLink(_google);
}

public ConnectionStatus CheckCommunicationLink(string url)
{
    //Test if we can get to Google (A happy website that should always be there).
    Uri googleURI = new Uri(url);
    if (!IsUrlReachable(googleURI, mGoogleTestString))
    {
        //The internet is not reachable.  No connection is available.
        return ConnectionStatus.NotConnected;
    }

    return ConnectionStatus.Connected;
}
0 голосов
/ 07 сентября 2010

Почему в вашем коде _google жестко задан код? Почему бы не поместить его в файл конфигурации, который вы можете изменить, например, для своего теста?

...