如果記憶體不足,C 中的new關鍵字將引發例外,但在 new 失敗時嘗試回傳“NO_MEMORY”的代碼下方。這很糟糕,因為它會引發std::bad_alloc例外。
我正在寫一個單元測驗(gtest)。如何創建一個場景來解決這個問題。
class base{
public: base(){
std::cout<<"base\n";
}
};
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);
}
uj5u.com熱心網友回復:
你調查過EXPECT_THROW嗎?
如果您不能絕對更改您的代碼(如果您想使用 gmock,這是必需的),您可以按照其他答案的建議全域多載 new 運算子。
但是,您應該謹慎執行此操作,因為該運算子被其他功能使用,包括 google 測驗中的功能。
一種方法是使用全域變數,使 new 運算子有條件地拋出。請注意,這不是最安全的方法,特別是如果您的程式使用多執行緒
以下是使用此方法和全域變數測驗您描述的場景的一種方法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 << "base\n"; }
};
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
uj5u.com熱心網友回復:
首先,我認為您需要捕獲例外,否則您的程式將永遠無法回傳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
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/425973.html
