Возможно ли провести модульное тестирование этого метода? - PullRequest
1 голос
/ 06 августа 2010

У меня есть следующий метод, для которого я пытаюсь написать модульный тест:

using StaticClass;           // writen by some one else, have a dll

namespace Test
{
  Class TestClass
   {
      public void DoSomething(string param1)
      {
         List<string> = StaticClass.GetList(param1)

         // sort the list and do other studd here
      }
  }
}

Когда я не уверен, как написать тест для метода DoSomething, это зависит от статического метода в другом классе. Вывод этого метода зависит от таких вещей, как база данных на этом компьютере, среда и некоторые другие факторы. Таким образом, если базы данных на двух машинах разные, один и тот же метод даст разные результаты. Все, что я знаю, это то, что GetList возвращает какое-то значение, и этот метод мог или не мог быть проверен модулем создателем этого класса.

Как я могу проверить такой метод? Можно ли сказать что-то вроде того, всякий раз, когда вызывается метод StaticClass.Getlist, возвращать пользовательский List<String>, который я создал в своей программе? Я пишу тесты на C #.

Спасибо

Ответы [ 6 ]

5 голосов
/ 06 августа 2010

Статические типы с методами, которые имеют побочные эффекты, хлопотны.

У вас есть два варианта:

  • Краткосрочный: напишите интерфейс с методом GetList с правильной сигнатурой. Затем напишите адаптер - класс, который реализует этот интерфейс и делегирует StaticClass внутренне. Передайте экземпляр этого типа адаптера в ваш класс как аргумент ctor или метод arg. Вызовите GetList на нем. Теперь вы можете использовать фиктивную среду для создания фиктивного объекта, передать его в свои тесты и настроить для возврата стандартных значений.
  • Долгосрочный: преобразование StaticClass в нестатический. Передайте это (вместо объекта адаптера); но для этого требуется доступ к исходному коду для StaticClass.
1 голос
/ 06 августа 2010

Это одна из причин, по которой использование статики таким образом иногда осуждается - хотя это и удобно, их очень трудно проверить.

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

Например, вы можете объявить

public interface ISomeonesDllService 
{
    IList<string> GetList(string param1);
}

Теперь создайте реализацию, которая использует StaticClass:

public class SomeonesDllService : ISomeonesDllService
{
    public IList<string> GetList(string param1)
    {
        return StaticClass.GetList(param1);
    }
}

Чтобы сделать TestClass тестируемым, вы можете добавить зависимость от этого внешнего сервиса в конструктор класса:

public class TestClass
{
    ISomeonesDllService dllService;

    public TestClass(ISomeonesDllService dllService)
    {
        this.dllService = dllService;
    }

    public void DoSomething(string param1)
    {
        IList<string> strings = dllService.GetList(param1);
        // do work
    }
}

Теперь вы можете очень легко протестировать метод DoSomething(), потому что в вашем тестовом приборе вы можете создать экземпляр TestClass, используя другую реализацию ISomeonesDllService. Вы можете вручную свернуть заглушку, которая просто возвращает статический список строк, или вы можете использовать фальшивый фреймворк, такой как Rhino.Mocks, чтобы настроить его для вас (что я рекомендую).

Таким образом, вы можете изолировать DoSomething() от работы внешних зависимостей.

0 голосов
/ 06 августа 2010

Сделайте StaticClass зависимостью, которую вы можете смоделировать с помощью Moq, Rhino и т. Д. Затем вы можете либо смоделировать StaticClass, чтобы вернуть известный List<string>, либо просто убедиться, что он вызывается через макет.

0 голосов
/ 06 августа 2010

Вы можете создать нестатическую оболочку для статического класса и использовать вместо нее оболочку.

что-то вроде

Class StaticClassWrapper {
  public List<string> GetList(string param1) {
    return StaticClass.GetList(param1);
  }
}

и затем использовать оболочку вместо статического классав вашем TestClass

0 голосов
/ 06 августа 2010

Если я увижу это право, этот метод не будет компилироваться. Но если вам нравится тестировать метод в статическом классе, его можно протестировать отдельно.

Метод в вашем классе ничего не возвращает. Если в системе есть только входы, вам не нужно это реализовывать.

0 голосов
/ 06 августа 2010

Вам понадобится использовать фиктивные объекты для проверки такого рода вещей. Смотрите эту замечательную статью: http://gamesfromwithin.com/mock-objects-friends-or-foes

По сути, вы создадите объект, который эмулирует объекты, с которыми он взаимодействует, а затем подтвердите свои ожидания.

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