调试器在进入时转到分配器.h,而不是方法体



下面的测试代码给我带来了麻烦。它编译正常,测试通过,但当调试并尝试进入第(*(行或第(**(行的函数AddPizza时,它会将我带到allocator.hallocator() throw() { }行,然后在下面继续。因此,我不需要进入方法来检查是否一切正常。例如,方法AddIngredient的前一行就不会发生这种情况。发生了什么,我的AddPizza实现或其他导致这种行为的方法是否有问题?顺便说一下,我在Windows10上使用Qtcreator。

TEST(TestPizzeria, TestPizza)
{
Pizzeria pizzeria;

try
{
pizzeria.AddIngredient("Tomato", "Red berry of the plant Solanum lycopersicum", 2);
pizzeria.AddIngredient("Mozzarella", "Traditionally southern Italian cheese", 3);

pizzeria.AddPizza("Margherita", vector<string> { "Tomato", "Mozzarella" });//(*)steping into it takes me to allocator.h  to line  `allocator() throw() { }` and then it continues below
pizzeria.AddPizza("Marinara", vector<string> { "Tomato" });
}
catch (const exception& exception)
{
FAIL();
}

try
{
pizzeria.AddPizza("Margherita", vector<string> { "Tomato", "Mozzarella" });// (**)also here
FAIL(); 
}
catch (const exception& exception)
{
EXPECT_THAT(std::string(exception.what()), Eq("Pizza already inserted"));
}
}

我在这里报告了AddPizza和AddIngredient的方法,以及所有必要的方法,以防万一:

class Ingredient {
public:
string Name;
int Price;
string Description;};
class Pizza {
vector<Ingredient> ingredients;
public:
string Name; 
void AddIngredient(const Ingredient& ingredient){ingredients.push_back(ingredient);}
};

class Pizzeria {
map<string, Ingredient> mapNameToIngredient;
map<string, Pizza> mapNameToPizza;

void AddPizza(const string &name, const vector<string> &ingredients)
{
if(mapNameToPizza.find(name) != mapNameToPizza.end())
{
throw runtime_error("Pizza already inserted");
}
else
{
Pizza pizza;
pizza.Name = name;
vector<string> ingredientss = ingredients;
for(vector<string>::iterator it = ingredientss.begin(); it != ingredientss.end(); it++)
{
Ingredient ingredient;
ingredient = FindIngredient(*it); 
pizza.AddIngredient(ingredient);
}
mapNameToPizza[name] = pizza;
}
}

void AddIngredient(const string &name, const string &description, const int &price)
{
if(mapNameToIngredient.find(name) != mapNameToIngredient.end())
{
throw runtime_error("Ingredient already inserted");
}
else
{
Ingredient ingredient;
ingredient.Name = name;
ingredient.Price = price;
ingredient.Description = description;                  
mapNameToIngredient[name] = ingredient;
}
}
const Ingredient &FindIngredient(const string &name) const
{
auto it = mapNameToIngredient.find(name);
if(it != mapNameToIngredient.end())
{
return it->second;
}
else
{
throw runtime_error("Ingredient not found");
}
}
};

GTest大量使用宏和全局变量,这是GTest框架本身的逻辑,如果您尝试使用步骤进行调试,您很可能会输入测试代码之外的辅助代码。

因此,建议在TEST正文的第一行中添加一个断点,如注释中提到的@11201ProgramAlarm。

您可以使用g++ -E来查看对原始c++代码进行预处理后的代码:

#include <gtest/gtest.h>
TEST(foo, bar) { ASSERT_EQ(true, true); }

即使对于这个单行测试,我们也会在预处理后得到一个73533行文件。我已经提取了尾部,并删除了一些文件名和行号信息,然后我们得到如下代码片段(它可能与您的不同,因为编译器和GTest版本可能不同(

static_assert(sizeof("foo") > 1, "test_suite_name must not be empty");
static_assert(sizeof("bar") > 1, "test_name must not be empty");
class foo_bar_Test : public ::testing::Test {
public:
foo_bar_Test() {}
private:
virtual void TestBody();
static ::testing::TestInfo* const test_info_ __attribute__((unused));
foo_bar_Test(foo_bar_Test const&) = delete;
void operator=(foo_bar_Test const&) = delete;
};
::testing::TestInfo* const foo_bar_Test ::test_info_ =
::testing::internal::MakeAndRegisterTestInfo(
"foo", "bar", nullptr, nullptr,
::testing::internal::CodeLocation("a.cpp", 3),
(::testing::internal::GetTestTypeId()),
::testing::internal::SuiteApiResolver<
::testing::Test>::GetSetUpCaseOrSuite("a.cpp", 3),
::testing::internal::SuiteApiResolver<
::testing::Test>::GetTearDownCaseOrSuite("a.cpp", 3),
new ::testing::internal::TestFactoryImpl<foo_bar_Test>);
void foo_bar_Test ::TestBody() {
switch (0)
case 0:
default:
if (const ::testing::AssertionResult gtest_ar =
(::testing::internal::EqHelper::Compare("true", "true", true,
true)))
;
else
return ::testing::internal::AssertHelper(
::testing::TestPartResult::kFatalFailure, "a.cpp", 3,
gtest_ar.failure_message()) = ::testing::Message();
}

我们可以看到,一个类是由TEST宏定义的,并且定义了一个全局变量,因此直接的步骤可以进入GTest的内部代码或从GTest的宏生成的代码。

相关内容

  • 没有找到相关文章

最新更新