如何模拟提升抛出异常?

时间:2015-10-26 18:46:35

标签: c++ unit-testing boost googletest gmock

我有使用boost与文件系统交互的代码,如下所示:

FileMigrater::migrate() const {
    //stuff
    try {
        boost::filesystem::create_direcotry(some_path_);
    } catch(const std::exception& e) {
        LOG(ERROR) << "Bad stuff happened";
        return MigrationResult::Failed;
    }
    //more stuff
}

我正在使用gmockgtestmigrate方法编写单元测试,我想为boost抛出的情况编写一个测试例外。理想情况下,我想编写一个看起来类似的单元测试(这个的语法是错误的,因为我一般都是新的c ++):

TEST_F(MyTest, boost_exception_test) {
    ON_CALL(boost_mock, create_directory()).Throw(std::exception);

    EXPECT_EQ(Migration::Failed, migrater.migrate());
}

问题在于我不知道如何创建boost_mock,或者即使这是解决问题的正确方法。

1 个答案:

答案 0 :(得分:1)

您的测试方法非常好。关键是无法模拟自由函数,而boost::filesystem::create_directory()是一个。

然而,documentation提出了解决问题的方法:

  

可以使用Google Mock来模拟免费功能(即a   C风格的功能或静态方法)。你只需要改写你的   代码使用接口(抽象类)。

     

不要直接调用自由函数(比如OpenFile),而是介绍   它的接口,并有一个调用free的具体子类   功能:

class FileInterface {
public:
 ...
 virtual bool Open(const char* path, const char* mode) = 0;
};
class File : public FileInterface {
public:
 ...
 virtual bool Open(const char* path, const char* mode) {
  return OpenFile(path, mode);
 }
};
     

您的代码应与FileInterface通信以打开文件。现在很容易嘲笑这个功能。

     

这可能看起来很麻烦,但实际上你经常有多个   相关的功能,你可以放在同一个界面,所以   每个函数的语法开销会低很多。

     

如果您担心会产生的性能开销   虚拟功能和分析确认您的关注,您可以   将其与mocking non-virtual methods的配方相结合。