0

我现在对单元测试非常深入,并且遇到了一个相当高级的问题。
有这个类 TrackLoader,它有一个名为 loadTracks(...) 的方法。我想测试该方法 - 不依赖于文件系统 - 这就是它变得棘手的地方

这是一个相当复杂的问题(恕我直言),所以也许一些代码会有所帮助

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 尝试从给定路径加载文件。为了打破文件系统依赖性,我必须模拟 Importer::parseTrack() 和 Importer::getTrack 以返回有效的曲目(不接触文件系统)。
但我看不到模拟实际 Importer 的方法。我可以模拟 ImporterFactory(使 ::createImporter 非静态),但我将如何模拟 Importer 本身?

这可以在不重构代码本身的情况下完成吗?

4

1 回答 1

2

经过一番摆弄,我实际上设法解决了这个问题。
这是代码:

//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)) 位,我能够通过 MockImporterFactory 注入 MockImporter。

于 2013-05-30T11:05:48.330 回答