У меня есть проект Embedded C / C ++, и я хочу написать для него модульные тесты с CppUTest. Один простой тест, который я хочу сделать, — убедиться, что во время теста вызывается определенная функция C.
Допустим, у меня есть две функции C, определенные в function.h
:
void success(void)
{
// ... Do Something on success
}
void bid_process(void)
{
bool happy = false;
// ... processing modifiying 'happy' and setting it to 'true'
if (happy)
success(); // Call to success
}
Я хочу проверить функцию big_process
и я хочу, чтобы мой тест не прошел, если success
не называется.
Для этого я написал несколько CppUTests в отдельном тестовом файле. test.cpp:
#include <CppUTest/CommandLineTestRunner.h>
#include "CppUTest/TestHarness.h"#include "CppUTestExt/MockSupport.h"
#ifdef __cplusplus
extern "C"{
#include "function.h"}
#endif
TEST_GROUP(TestGroup)
{
void teardown()
{
mock().clear();
}
};TEST(TestGroup, Test_big_process)
{
mock().expectOneCall("success"); // success should be called by the call to big process
big_process();
mock().checkExpectations();
}
Я проверил вручную, что big_process
работает нормально и звонит success
но теперь я хочу, чтобы мой тест сделал это. Но тест не проходит и говорит мне:
Mock Failure: Expected call did not happen.
EXPECTED calls that did NOT happen:
success -> no parameters
Поэтому мой вопрос прост: как обеспечить success
называется во время big_process
?
Вы правильно устанавливаете фиктивные ожидания, но не связываете макет с функцией success ().
Это объясняет похожую проблему: https://github.com/cpputest/cpputest/issues/1054
Я считаю, что поддержка макетов в CppUTest является инвазивной, то есть вам также необходимо добавить поддержку макетов в ваш производственный код. Пример:
void success(void)
{
mock().actualCall("success");
....
}
Для неинвазивного модульного тестирования простого C-кода вместо этого можно использовать, например, препроцессор или соединительные швы. Проверьте большую книгу Майкла Перса Эффективная работа с устаревшим кодом для деталей.
На самом деле, вы можете найти отрывок из этой книги, охватывающий эти типы швов Вот. Я бы порекомендовал любому программисту Си читать эту книгу — это бесценно.
Вместо фиктивной библиотеки cpputest, возможно, вы могли бы использовать другой фреймворк, такой как, например, фальшивый фреймворк. Увидеть https://github.com/meekrosoft/fff/blob/master/README.md
Это позволяет вам писать легковесные функции-заглушки, которые могут заменить фактическую реализацию тестовым двойным. Это может быть сделано на этапе связывания. Свяжите реализацию fff перед фактической реализацией, чтобы компоновщик извлек фальшивую реализацию.