Поблочное тестирование функции, целями которых являются побочные эффекты

Как был бы Вы модульный тест do_int_to_string_conversion?

#include <string>
#include <iostream>

void do_int_to_string_conversion(int i, std::string& s) {
    switch(i) {
    case 1:
        s="1";
        break;
    case 2:
        s="2";
        break;
    default:
        s ="Nix";
    }
}

int main(int argc, char** argv){
    std::string little_s;

    do_int_to_string_conversion(1, little_s);
    do_int_to_string_conversion(2, little_s);
    do_int_to_string_conversion(3, little_s);

}
5
задан David 6 May 2010 в 17:04
поделиться

5 ответов

Я предполагаю, что это просто пример. Почему вы не можете утверждать значение little_s после каждого вызова?

do_int_to_string_conversion(1, little_s);
assert_are_equal("1", little_s);
9
ответ дан 18 December 2019 в 06:21
поделиться

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

-1
ответ дан 18 December 2019 в 06:21
поделиться

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

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

Я бы начал с 1) разделения его на логические функции и 2) предоставления потока в качестве параметра.

std::string convert_int(int val) {
    switch (val) { 
       case 1: return "1";
       case 2: return "2";
       default: return "Nix";
   }
}

std::ostream &write_string(std::ostream &os, std::string const &s) { 
    return os << s;
}

Я не включил ничего, чтобы (конкретно) изменить передаваемую извне строку - очевидно, вы можете присвоить возвращаемое значение из convert_int , как считаете нужным, и значение строки, которая была передана в в любом случае не использовался.

По правде говоря, write_string - хороший кандидат для полного исключения, но, поскольку у вас была такая базовая возможность, мы пока сохраним ее. Проверить их относительно просто - для convert_int мы смотрим на строку, которую он возвращает, и сравниваем с ожидаемой. Для write_string мы можем передать stringstream вместо обычного ostream - тогда мы можем использовать .str () , чтобы получить это результат в виде строки и (снова) сравнить с тем, что мы ожидаем.

11
ответ дан 18 December 2019 в 06:21
поделиться

Я бы изменил do_int_to_string_conversion так, чтобы он выполнял только одно действие (преобразовывал in в строку).

void do_int_to_string_conversion(int i, std::string& s) {
    switch(i) { ... }
}

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

Если бы мне понадобилась функция, выводящая результат преобразования, я бы поместил ее в отдельную функцию и параметризовал бы выходной поток.

void output_int(int i, ostream &stream) {
    std::string s;
    do_int_to_string_conversion(i, s);
    stream << s;
}

Для модульного тестирования я бы передал объект std :: stringstream и проверил результат.

3
ответ дан 18 December 2019 в 06:21
поделиться

Если вам действительно нужно убедиться, что вывод был записан, вам нужно разорвать вашу зависимость от ] std :: cout и использовать другой std :: ostream во время тестов.

Это может быть так же просто, как глобальная переменная:

#if PRODUCTION
std::ostream my_output = std::cout;
#else
std::ostream my_output = std::ostringstream;
#endif

void setup()
{
    my_output = std::ostringstream;
}

void print_hello()
{
    my_output << "hello";
}

void test_hello_was_printed()
{
    print_hello();
    ASSERT("hello" == my_output.str());
}

Или что-то подобное с этим эффектом.

3
ответ дан 18 December 2019 в 06:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: