Как бы я высмеял объект, созданный в "тестируемом методе"?
Я сейчас довольно глубоко разбираюсь с юнит-тестами и столкнулся с довольно сложной проблемой.
Есть этот класс TrackLoader, у которого есть метод loadTracks (...). Я хотел бы протестировать этот метод - без зависимости от файловой системы - и вот где он становится сложным
Это довольно сложная проблема (imho), поэтому, возможно, какой-то код будет полезен
void TrackLoader::loadTracks(QDomNode tracks, DataManager& dataManager)
{
QDomNodeList trackList = tracks.childNodes();
for(int i = 0; i < trackList.size(); ++i)
{
QString filePath = trackList.at(i).toElement().attribute("filePath");
QSharedPointer<Importer> importer = ImporterFactory::createImporter(filePath);
importer->parseTrack();
dataManager.addTrack(filePath, importer->getTrack());
}
Основная проблема заключается в том, что фактический импортер пытается загрузить файл по указанному пути. Чтобы сломать зависимость файловой системы, мне нужно было бы смоделировать Importer::parseTrack() и Importer::getTrack, чтобы вернуть действительные треки (не касаясь файловой системы).
Но я не вижу способа издеваться над настоящим импортером. Я мог бы издеваться над ImporterFactory (делая::createImporter нестатичным), но как бы я высмеял сам Importer?
Можно ли это сделать без рефакторинга самого кода?
1 ответ
После некоторой возни мне действительно удалось решить проблему.
Вот код:
//this Importer is used to create mockTracks
std::shared_ptr<MockImporter> datImporter = std::make_shared<MockImporter>();
EXPECT_CALL(*(datImporter.get()), parseSource()).Times(3);
EXPECT_CALL(*(datImporter.get()), getSource()).Times(3).WillRepeatedly(Return(mockedTrack()));
//this factory is used to inject the actual MockImporter
std::shared_ptr<MockImporterFactory> importerFactory = std::make_shared<MockImporterFactory>();
EXPECT_CALL(*(importerFactory.get()), createImporter(QString("Test1.DAT"))).WillOnce(Return(datImporter));
EXPECT_CALL(*(importerFactory.get()), createImporter(QString("Test2.DAT"))).WillOnce(Return(datImporter));
EXPECT_CALL(*(importerFactory.get()), createImporter(QString("Test3.DAT"))).WillOnce(Return(datImporter));
//this injects the MockImporterFactory and runs the code.
TrackLoaderPtr trackLoader = std::make_shared<TrackLoader>(importerFactory);
trackLoader->loadTracks(identNode(), _dataManager);
По сути, ImporterFactory был сначала осмеян, чтобы убедиться, что он вообще создает любого Importer.
Добавив бит.WillOnce(Return(datImporter)), я смог внедрить MockImporter через MockImporterFactory.