2014-12-18 3 views
0

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

Это один из моих тестов:

void test_is_location_free() { 
    Storage test_storage = new_storage(); 
    Item test_item; 
    test_storage->inventory[5] = test_item; 
    test_storage->inventory[5].loc.shelf = 'A'; 
    test_storage->inventory[5].loc.place = 1; 

    CU_ASSERT(!is_location_free(test_storage, test_item, 'A', 1)); 
} 

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

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

Suite: HELPER FUNCTIONS 
    Test: compare_char() ...passed 
    Test: first_empty_position() ...passed 
    Test: is_location_free() ...Location not empty, try again! 
Shelf: 

Есть ли способ игнорировать все входы пользователей в целом, или, возможно, определить будущее пользовательский ввод, который будет использовать мой тестовый пример?

Спасибо!

+0

Вы можете использовать сказать '#define TESTING', а затем' #ifdef ТЕСТИРОВАНИЕ ... #else ... # endif', чтобы заменить входы готовыми статическими данными. –

+0

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

ответ

0

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

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

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

+0

Да, функции вроде бы перепутаны со всеми этими входами пользователя, включенными в них. Я использую fgets() с stdin в функции, но я не уверен, как изменить его, прежде чем вызывать его. В любом случае, я думаю, что лучше всего будет реорганизовать весь код. Благодаря! – drante

+0

Пока вам не нужно возвращаться к исходному потоку stdin, функция freopen сделает трюк. Вот ссылка на большее обсуждение темы: [link] (http://stackoverflow.com/questions/584868/rerouting-stdin-and-stdout-from-c) –

+0

«Не смешивайте форму с функцией». –

0

Вы можете легко написать собственную версию fgets() для ваших модульных тестов. Это называется насмешкой и очень распространено в модульном тестировании. Нечто подобное должно работать:

static char test_input[MAX_INPUT]; 

char *fgets(char *s, int size, FILE *stream) 
{ 
    strncpy(s, test_input, size); 

    return s; 
} 

Затем переписать тест так:

void test_is_location_free() { 
    Storage test_storage = new_storage(); 
    Item test_item; 
    test_storage->inventory[5] = test_item; 
    test_storage->inventory[5].loc.shelf = 'A'; 
    test_storage->inventory[5].loc.place = 1; 

    strncpy(test_input, "test input data", MAX_INPUT); 

    CU_ASSERT(!is_location_free(test_storage, test_item, 'A', 1)); 
} 
Смежные вопросы