对新关键字进行GtestC++中的



new关键字将在内存不足但下面的代码试图返回"时抛出异常;NO_ MEMORY";当new失败时。这很糟糕,因为它将引发std::bad_alloc异常。

我正在写一个单元测试(gtest(。如何创建一个场景来捕捉这个问题。

class base{

public: base(){
std::cout<<"basen";
}
};

std::string getInstance(base** obj){
base *bObject = new base();
*obj = bObject; //updated
return (NULL == bObject) ? "NO_MEMORY" : "SUCCESS"; // here is problem if new fail it raise an exception. How to write unit test to catch this?
}
int main()
{

base *base_obj;
getInstance(&base_obj);
}

您研究过EXPECT_THROW吗?

如果你不能完全更改你的代码(如果你想使用gmock,这是必需的(,你可以按照另一个答案的建议全局重载新的运算符。

然而,你应该小心地这样做,因为这个运算符被其他函数使用,包括谷歌测试中的函数。

一种方法是使用一个全局变量,使新操作符有条件地抛出。请注意,这不是最安全的方法,特别是如果您的程序使用多线程

以下是使用此方法和全局变量g_testing测试您描述的场景的一种方法。

// https://stackoverflow.com/questions/70925635/gtest-on-new-keyword
#include "gtest/gtest.h"
// Global variable that indicates we are testing. In this case the global new
// operator throws.
bool g_testing = false;
// Overloading Global new operator
void *operator new(size_t sz) {
void *m = malloc(sz);
if (g_testing) {
throw std::bad_alloc();
}
return m;
}
class base {
public:
base() { std::cout << "basen"; }
};
std::string getInstance(base **obj) {
base *bObject = new base();
*obj = bObject;  // updated
return (NULL == bObject)
? "NO_MEMORY"
: "SUCCESS";  // here is problem if new fail it raise an exception.
// How to write unit test to catch this?
}
TEST(Test_New, Failure) {
base *base_obj;
// Simple usage of EXPECT_THROW. This one should THROW.
g_testing = true;
EXPECT_THROW(getInstance(&base_obj), std::bad_alloc);
g_testing = false;
std::string result1;
// You can put a block of code in it:
g_testing = true;
EXPECT_THROW({ result1 = getInstance(&base_obj); }, std::bad_alloc);
g_testing = false;
EXPECT_NE(result1, "SUCCESS");
}
TEST(Test_New, Success) {
base *base_obj;
std::string result2;
// This one should NOT throw an exception.
EXPECT_NO_THROW({ result2 = getInstance(&base_obj); });
EXPECT_EQ(result2, "SUCCESS");
}

下面是您的工作示例:https://godbolt.org/z/xffEoW9Kd

首先,我认为您需要捕获异常,否则您的程序将永远无法返回NO_MEMORY:

std::string getInstance(base **obj) {
try {
if (!obj)
throw std::invalid_argument("");
*obj = new base();
return "SUCCESS";
}
catch (const std::bad_alloc& e) {
return "NO_MEMORY";
}
catch (...) {
return "UNDEFINED_ERROR";
}
}

测试这一点的一种快速而肮脏的方法是让构造函数(或重载的new(抛出std::bad_alloc:

#ifdef UNIT_TESTING
// simulate there is no memory
base::base() { throw std::bad_alloc; }
#else
base::base() { }
#endif

但我想正确的方法是使用类似mockcpp 的东西

编辑:由于你使用的是gtest,你可能更喜欢使用Google Mock来模拟base,因为构造函数抛出bad_alloc,而不是base::base的脏替换

相关内容

  • 没有找到相关文章

最新更新