我现在非常深入到单元测试中并且遇到了相当高级的问题。
这个类的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尝试从给定路径加载文件。要打破文件系统依赖性,我必须模拟Importer :: parseTrack()和Importer :: getTrack来返回有效的Tracks(不触及文件系统)。
但我没有看到嘲笑实际进口商的方法。我可以模拟ImporterFactory(使:: createImporter非静态),但是如何模拟Importer本身呢?
这可以在不重构代码的情况下完成吗?
答案 0 :(得分: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。