Проблемные модульные функции тестирования, которые содержат файловый ввод / вывод с использованием Visual Studio Native cpp Unite Testing
У меня есть этот кусок кода, который подсчитывает количество случаев, когда фраза существует в текстовом файле. Когда я вызываю это из функции main(), она работает как положено.
Когда я пытаюсь написать для него модульный тест, при открытии файла происходит сбой, возвращая -1 (см. Код ниже).
Вот код для моей функции countInstances:
int countInstances(string phrase, string filename) {
ifstream file;
file.open(filename);
if (file.is_open) {
stringstream buffer;
buffer << file.rdbuf();
file.close();
string contents = buffer.str();
int fileLength = contents.length();
int phraseLength = phrase.length();
int instances = 0;
// Goes through entire contents
for(int i = 0; i < fileLength - phraseLength; i++){
int j;
// Now checks to see if the phrase is in contents
for (j = 0; j < phraseLength; j++) {
if (contents[i + j] != phrase[j])
break;
}
// Checks to see if the entire phrase existed
if (j == phraseLength) {
instances++;
j = 0;
}
}
return instances;
}
else {
return -1;
}
}
Мой юнит тест выглядит так:
namespace Tests
{
TEST_CLASS(UnitTests)
{
public:
TEST_METHOD(CountInstances) {
/*
countInstances(string, string) :
countInstances should simply check the amount of times that
the passed phrase / word appears within the given filename
*/
int expected = 3;
int actual = countInstances("word", "../smudger/test.txt");
Assert::AreEqual(expected, actual);
}
};
}
Для теста CountInstance я получаю следующее сообщение:
Сообщение: Утвердить не удалось. Ожидаемое:<3> фактическое:<- 1>
Любые идеи о том, откуда возникла моя проблема и как я мог бы решить ее? Благодарю.
1 ответ
Хотя наличие зависимостей файловой системы в модульных тестах не идеально, вы можете просто создать библиотеки DLL модульного теста в папке, содержащей файлы тестовых данных.
https://stackru.com/image s/0fca1eb92078ae61b38ac3ae6e56651825fdae5d.png
Тот факт, что ваши тесты зависят от того, какой файл присутствует в файловой системе, делает ваши тесты сложными в обслуживании и понимании, потому что информация для каждого тестового случая распределена. Если вы позже измените макет каталога, тесты могут снова не пройти.
Лучшим способом модульного тестирования вашего кода было бы извлечение чтения содержимого файла в собственную функцию, которая, например, возвращает строку с содержимым файла. Для начала поместите эту функцию в отдельный файл.
В ваших тестах вы можете затем заменить эту функцию на mock: mock возвращает строку, но не читает ее из файла - вместо этого ваш тестовый код предоставляет строку, которую функция затем должна вернуть. Поскольку исходная функция была помещена в отдельный файл, вы можете создать исполняемый файл теста, не связывая исходную функцию, а вместо этого смоделированную функцию.
Таким образом, вы в своих тестах не зависите от файловой системы. Вы можете легко создать большое количество тестовых случаев и иметь все под контролем из тестового кода.
Есть более продвинутые способы для достижения этой цели, но этот ответ просто призван дать вам отправную точку. Если вы хотите узнать больше, ищите инъекцию зависимостей, насмешки, инверсию управления.