TDD подход для сложной функции - PullRequest
4 голосов
/ 05 мая 2010

У меня есть метод в классе, для которого они имеют несколько разных результатов (на основе ответов на события и т. Д.). Но это единственная атомарная функция, которая используется другими приложениями.

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

И поэтому мой вопрос заключается в том, как можно / нужно ли мне легко подойти к решению в стиле TDD, чтобы убедиться, что единственный вызываемый метод работает правильно, без большого дублирования в тестировании или большого количества настроек, необходимых для каждого теста?

Я рассмотрел / посмотрел на перемещение блоков функциональности в другой класс и использую Mocking для имитации ответов используемых функций, но это не правильно, и отдельные методы должны записывать переменные в основном классе ( он чувствовал себя действительно хит Хин Робинсон).

Код выглядит примерно так (я удалил много параметров, чтобы прояснить ситуацию, а также немного ненужного кода).

public void MethodToTest(string parameter)
{
    IResponse x = null;

    if (function1(parameter))
    {

        if (!function2(parameter,out x))
        {
            function3(parameter, out x);
        }
    }

    // ...
    // more bits of code here
    // ...

    if (x != null)
    {
        x.Success();
    }
}

Ответы [ 4 ]

1 голос
/ 05 мая 2010

Я думаю, вы бы упростили свою жизнь, если бы не использовали ключевое слово out и переписали код так, чтобы функции либо проверяли какое-либо условие в ответе, либо ИЛИ изменяли ответ, но не оба. Что-то вроде:

public void MethodToTest(string parameter)
{
    IResponse x = null;

    if (function1(parameter))
    {

        if (!function2Check(parameter, x))
        {
            x = function2Transform(parameter, x);
            x = function3(parameter, x);
        }
    }

    // ...
    // more bits of code here
    // ...

    if (x != null)
    {
        x.Success();
    }
}

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

public void MethodToTest(string parameter)
{
    IResponse x = ResponseBuilder.BuildResponse(parameter);

    if (x != null)
    {
        x.Success();
    }
}

... где BuildResponse - это место, где будут находиться все ваши текущие тесты, и тест для MethodToTest теперь должен быть довольно легко издеваться над ResponseBuilder.

0 голосов
/ 05 мая 2010

Наилучшим вариантом действительно будет функция пересмешки1, 2, 3 и т. Д. Если вы не можете переместить свои функции в отдельный класс, вы можете использовать вложенные классы для перемещения функций, они могут получить доступ к данным во внешнем учебный класс. После этого вы сможете использовать mocks вместо вложенных классов для тестирования.

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

0 голосов
/ 05 мая 2010

В этом случае, я думаю, вы бы просто высмеяли вызовы методов, как вы упомянули.

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

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

0 голосов
/ 05 мая 2010

ИМХО, у вас есть пара вариантов здесь:

  1. Разбейте внутренние функции на другой класс, чтобы вы могли их высмеивать и проверять, что они вызываются. (о котором вы уже упоминали)
  2. Похоже, что другие созданные вами методы являются закрытыми, и это единственный открытый интерфейс для этих методов. Если это так, вы должны выполнить эти тестовые примеры через эту функцию и проверить результаты (вы сказали, что эти закрытые методы изменяют переменные класса) вместо того, чтобы тестировать частные методы. Если это слишком больно, я бы рассмотрел переделку вашего дизайна.

Мне кажется, этот класс пытается сделать больше, чем одну вещь. Например, первая функция не возвращает ответ, а две другие делают. В своем описании вы сказали, что функция сложная и принимает много параметров. Это оба признака того, что вам нужно реорганизовать ваш дизайн.

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