【问题标题】:How to Skip a Portion of the ”Code” in the source code while doing GoogleTest如何在进行 GoogleTest 时跳过源代码中的一部分“代码”
【发布时间】:2016-03-16 16:00:20
【问题描述】:

我尝试在源代码中使用调试标志添加 (GOOGLE_TEST) 并在 TEST/Makefile.am 中定义它。但事情没有奏效。我正在使用 C++ 语言。 注意:我不想更改 SRC 目录代码中会影响生产代码及其 Makefile.am 的任何内容

SRC 目录中的测试类

class Common: public Thread {
 public:
  friend class test_common;
  Common {
  }
  ~Common () {
  }
  virtual void ThreadMain();
 protected:
  virtual void ProcessData(void);
};
void Common::ProcessData(void) {
  #ifndef __GOOGLE_TEST__
  while (1) { }
  #endif
}

测试目录中的TESTCODE

class test_common : public ::testing::Test {
};
TEST_F(test_common, create_common) {
    Common commonObj();
    commonObj. ProcessData ();
}

输出

即使在 test/makefile.am 中定义了标志之后,GTest 仍卡在 While 循环部分

【问题讨论】:

  • 你是在编译SRC目录中的代码时定义__GOOGLE_TEST__,还是只在编译测试时定义__GOOGLE_TEST__
  • @Antonio Pérez:仅在编译测试时。
  • 那就是原因:)
  • @Antonio Pérez:如果我在源代码 make 文件中定义,那么该功能将不适用于他们 :-)
  • 那么不要在源代码中定义它而是作为编译选项,即-D__GOOGLE_TEST__,仅在编译测试时。无论如何,用于测试的条件编译通常表明您应该将不想在测试中运行的代码分解到不同的类中,然后注入依赖项,以便您可以在测试中模拟它。

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


【解决方案1】:

不要依赖编译标志,在不影响生产代码的情况下使用 GMOCK 方法摆脱 while (1) 循环,代码如下:

测试代码:

class test_common : public ::testing::Test {
};
TEST_F(test_common, create_common) {
    Common commonObj();
    ON_CALL(mock_if, GetBool())
      .WillByDefault(Return(true));
    EXPECT_CALL(mock_if, GetBool())
      .Times(AtLeast(1))
      .WillOnce(Return(true))
      .WillOnce(Return(false));
    commonObj. ProcessData ();
}

抽象代码:

class AbstractIf {
 public:
  AbstractIf (void) = default;
  virtual ~AbstractIf (void) = default;
  virtual bool GetBool() = 0;
};

模拟代码:

class MockIf : public AbstractIf {
  public:
    MOCK_METHOD0(GetBool,bool());
};

源代码:

class Common: public Thread {
 public:
  friend class test_common;
  Common {
  }
  ~Common () {
  }
  virtual void ThreadMain();
 protected:
  virtual void ProcessData(void);
  AbstractIf *prov_fl_if_;
};
void Common::ProcessData(void) {
  while (prov_fl_if_->GetBool())  { }
}

通过这种方式我们可以跳过我们想要的部分代码而不影响生产代码

【讨论】:

    【解决方案2】:

    没有办法让一个编译单元的#define 值影响另一个以前编译单元的编译。鉴于您已经规定不想做的事情清单,您将不得不使用某种形式的运行时恶作剧。

    你可以让 ProcessData 接受一个参数来确定循环是否应该迭代:

    void ProcessData(bool once=false);
    
    void Common::ProcessData(bool once) {
        do {
        // ... your loop code
        } while (!once);
    }
    

    或者您可以使用在模块中定义的全局变量,其中包含您的main(),我们称之为main.cpp

    生产main.cpp:

    const bool g_isDebugMode = false;
    

    单元测试main.cpp:

    const bool g_isDebugMode = true;
    

    main.h

    extern const bool g_isDebugMode;
    

    现在您可以针对此变量编写运行时测试。

    do {
    // your code
    } while (g_isDebugMode == false);
    

    【讨论】:

    • 首先感谢您的尝试!!如果我们通过 ThreadMain() 调用 ProcessData() 是不可能的(就像将 bool 变量传递给源代码中的函数内部的函数。这似乎是源代码中的开销)。就 GTest 而言,我们没有 main.h 等来将来自不同编译单元的全局变量外部化。 @所有其他使用 Gmock 的方式等..(我不知道..)
    猜你喜欢
    • 2014-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-25
    • 1970-01-01
    • 2020-04-24
    • 2011-05-13
    相关资源
    最近更新 更多