Я очень новичок в тестировании, поэтому, пожалуйста, дайте мне знать, если я в какой-то момент просто ухожу в совершенно неправильном направлении. Сказав это, предположим, что я хочу проверить следующую функцию, foo.
int foo(int i) {
//Lots of code here
i = bar();
//Some more changes to i happen here, conditional on what bar returned
return i;
}
В этом примере и foo, и bar являются функциями, написанными мной, и я уже тестировал bar.
Поскольку вывод foo зависит от вывода bar, я предполагаю, что для проверки foo мне нужно создать макет bar. Чтобы сделать это, и предположив, что определение bar хранится в отдельном исходном файле от foo, я мог бы создать новый исходный файл, включить его вместо того, где находится фактическое определение bar, и поместить макет бара в этом файле.
int bar(void) {
return HARD_CODED_VALUE;
}
Однако у этого подхода есть 2 проблемы:
1) Что произойдет, если bar возвращает несколько значений (например, код ошибки или фактическое значение), и мне нужно убедиться, что foo правильно реагирует на каждую возможность? Я не могу создать несколько определений для бара. Одна мысль, которая у меня была, заключалась в том, чтобы создать статический int в bar, а затем увеличивать его каждый раз, когда вызывается bar. Тогда у меня просто есть условие для этого int, вызывать bar несколько раз и, таким образом, возвращать несколько значений. Однако я не уверен, является ли введение более сложной логики в фиктивную функцию хорошей практикой или есть ли лучший способ добиться этого:
int bar(void) {
static int i = 0;
i++;
if(i == 1) {
return HARD_CODED_VALUE_1
}
else if(i == 2) {
return HARD_CODED_VALUE_2
}
else {
fprintf(stderr, "You called bar too many times\n");
exit(1);
}
}
2) Что произойдет, если bar находится в том же исходном файле, что и foo? Я не могу переопределить ни бар, ни разделить foo и bar, не изменив мой исходный код, что было бы настоящей болью.