- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
关闭。这个问题是 opinion-based 。它目前不接受答案。
想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文来回答。
3年前关闭。
Improve this question
我想使用 GoogleTest 测试一些私有(private)方法。
class Foo
{
private:
int bar(...)
}
class Foo
{
private:
FRIEND_TEST(Foo, barReturnsZero);
int bar(...);
}
TEST(Foo, barReturnsZero)
{
Foo foo;
EXPECT_EQ(foo.bar(...), 0);
}
class Foo
{
friend class FooTest;
private:
int bar(...);
}
class FooTest : public ::testing::Test
{
protected:
int bar(...) { foo.bar(...); }
private:
Foo foo;
}
TEST_F(FooTest, barReturnsZero)
{
EXPECT_EQ(bar(...), 0);
}
最佳答案
至少还有两个选择。我将通过解释某种情况列出一些您应该考虑的其他选项。
选项 4:
考虑重构您的代码,以便您要测试的部分在另一个类中是公开的。通常,当您想测试一个类的私有(private)方法时,这是一个糟糕设计的迹象。我看到的最常见的(反)模式之一是 Michael Feathers 所说的“冰山”类。 “冰山”类有一个公共(public)方法,其余的都是私有(private)的(这就是测试私有(private)方法很诱人的原因)。它可能看起来像这样:
例如,您可能希望通过在字符串上连续调用 GetNextToken()
并查看它返回预期结果来测试它。像这样的函数确实需要进行测试:这种行为并非微不足道,特别是如果您的标记规则很复杂。让我们假设它不是那么复杂,我们只想用空间分隔标记。所以你写了一个测试,也许它看起来像这样:
TEST(RuleEvaluator, canParseSpaceDelimtedTokens)
{
std::string input_string = "1 2 test bar";
RuleEvaluator re = RuleEvaluator(input_string);
EXPECT_EQ(re.GetNextToken(), "1");
EXPECT_EQ(re.GetNextToken(), "2");
EXPECT_EQ(re.GetNextToken(), "test");
EXPECT_EQ(re.GetNextToken(), "bar");
EXPECT_EQ(re.HasMoreTokens(), false);
}
GetNextToken()
是私有(private)函数!所以我们不能像这样测试它,因为它甚至不会编译。但是如何更改
RuleEvaluator
类以遵循单一职责原则(Single Responsibility Principle)呢?例如,我们似乎将解析器、分词器和求值器集中在一个类中。把这些责任分开不是更好吗?最重要的是,如果您创建一个
Tokenizer
类,那么它的公共(public)方法将是
HasMoreTokens()
和
GetNextTokens()
。
RuleEvaluator
类可以有一个
Tokenizer
对象作为成员。现在,我们可以保持与上面相同的测试,除了我们正在测试
Tokenizer
类而不是
RuleEvaluator
类。
GetNextToken()
方法现在在
Tokenizer
类上是公开的:
TEST(Tokenizer, canParseSpaceDelimtedTokens)
{
std::string input_string = "1 2 test bar";
Tokenizer tokenizer = Tokenizer(input_string);
EXPECT_EQ(tokenizer.GetNextToken(), "1");
EXPECT_EQ(tokenizer.GetNextToken(), "2");
EXPECT_EQ(tokenizer.GetNextToken(), "test");
EXPECT_EQ(tokenizer.GetNextToken(), "bar");
EXPECT_EQ(tokenizer.HasMoreTokens(), false);
}
FRIEND_TEST
或将它们公开)会导致测试重复 。你真的不想要这个,因为没有什么比你的测试套件拖慢你更伤人的了。它应该减少开发时间并降低维护成本!如果您测试通过公共(public)接口(interface)以其他方式测试的私有(private)方法,则测试套件很可能会反其道而行之,并积极增加维护成本并增加开发时间。当您将私有(private)函数设为公开时,或者如果您使用诸如
FRIEND_TEST
之类的东西,您通常最终会后悔。
Tokenizer
类的可能实现:
SplitUpByDelimiter()
负责返回一个
std::vector<std::string>
,这样 vector 中的每个元素都是一个标记。此外,让我们说
GetNextToken()
只是这个 vector 上的一个迭代器。所以你的测试可能是这样的:
TEST(Tokenizer, canParseSpaceDelimtedTokens)
{
std::string input_string = "1 2 test bar";
Tokenizer tokenizer = Tokenizer(input_string);
EXPECT_EQ(tokenizer.GetNextToken(), "1");
EXPECT_EQ(tokenizer.GetNextToken(), "2");
EXPECT_EQ(tokenizer.GetNextToken(), "test");
EXPECT_EQ(tokenizer.GetNextToken(), "bar");
EXPECT_EQ(tokenizer.HasMoreTokens(), false);
}
// Pretend we have some class for a FRIEND_TEST
TEST_F(TokenizerTest, canGenerateSpaceDelimtedTokens)
{
std::string input_string = "1 2 test bar";
Tokenizer tokenizer = Tokenizer(input_string);
std::vector<std::string> result = tokenizer.SplitUpByDelimiter(" ");
EXPECT_EQ(result.size(), 4);
EXPECT_EQ(result[0], "1");
EXPECT_EQ(result[1], "2");
EXPECT_EQ(result[2], "test");
EXPECT_EQ(result[3], "bar");
}
FRIEND_TEST
之类的东西称为“摸索工具”,因为它试图触摸别人的隐私部位。
关于c++ - 使用 GoogleTest 测试私有(private)方法的最佳方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47354280/
gtest 有没有办法让内联/测试用例甚至测试超时。 例如,我想做类似的事情: EXPECT_TIMEOUT(5 秒,myFunction()); 我从 2010 年 12 月 9 日发现这个问题 g
我正在尝试googletest。 以前,我一直在使用Boost测试,并且一直在使用宏BOOST_AUTO_TEST_SUITE将测试分组到Testsuite中。 这使junit报告更具可读性。 我在g
我的 googletest 具有以下结构: void check(Arg a1, Arg a2) { EXPECT_TRUE(a1 == a2); } TEST(s, t) { a1 =
我有 2 种方法的类(class) class A { void Fun() { if(FunRet()>0){///} else {///} } int FunRet()
我正在使用 gtest 编写一个类型参数化的测试装置,我看到了 not declared in this scope当我尝试使用夹具类的成员时出现编译器错误。 当我不使用类型参数化装置时,我可以很好地
我在gtest中使用值参数化测试。例如,如果我写 INSTANTIATE_TEST_CASE_P(InstantiationName, FooTest,
我有一个用C ++编写的程序,其中一些子文件夹包含链接的库。有一个顶级SConscript,它在子文件夹/库中调用SConscript文件。 在库cpp中,有一个GTest: TEST(X, just
为了对某些代码进行 BDD 风格的测试,我有一组测试,我想针对多个场景执行这些测试。我已经在 C# 中使用 NUnit & NSubstitute 多次这样做了,但是我正在努力使用 GoogleTes
我正在尝试为向量编写测试。 对于 STL 容器,我尝试过: EXPECT_THAT(float_vec1, ElementsAreArray(float_vec2)); 但是我需要插入一个边距。 有没
使用 Google Test 1.6(Windows 7、Visual Studio C++)。如何关闭给定的测试? (又名如何阻止测试运行)。除了注释掉整个测试之外,我还能做些什么吗? 最佳答案 d
如果一个测试有多个EXPECT_*语句 TEST_F(TestClass, ServerTest) { // Start server server_.start(); usl
当我编写测试夹具来测试一些 C 代码时,我使用相同的设置: https://github.com/google/googletest/blob/master/googletest/docs/prime
给定一个包含数千个测试的大型项目,其中一些测试需要几分钟才能完成。按顺序执行时,整套测试需要一个多小时才能完成。通过并行执行测试可以减少测试时间。 据我所知,没有办法直接从 googletest/mo
我在 googletest 中运行一些单元测试。我期望对模拟函数的某些调用 (EXPECT_CALL(*rtosMock, xQueueGenericSend( arg , _, _, _)).Tim
我刚刚开始学习 googletesting,并且正在使用它。我想使用参数化测试来检查类的函数成员返回的值是否是它应该的值。我已经声明了一个名为“myClass”的类,在其中我使用构造函数设置了一个变量
我有一个抽象基类,它具有处理线程生命周期(启动、停止、加入)的逻辑。线程中执行的工作依赖于实例化的派生类,派生类有几个。 基类如下所示: class Base { public: Base(i
是什么原因,为什么GoogleTest对参数计数使用引用? testing::InitGoogleTest(&argc, argv); (我的意思是:据我了解,这是一个输入参数,没有任何区别是否提
我正在为遗留代码创建测试,想知道是否可以像这样检查类的成员变量的值(我知道我下面的代码非常糟糕,糟糕的例子:/。希望只是请关注关于问题): class Animal { public: RESU
这是我的测试夹具:https://github.com/patrykbajos/ZinotEngine/blob/master/src/tests/core/MapResMgrTest.cpp .此可
我想知道,是否有可能检查失败的 ASSERT 或 EXPECT 语句,这些语句发生在被调用函数内部并且独立于任何其他或先前的失败 ASSERT/EXPECT 语句。基本上: void subcheck
我是一名优秀的程序员,十分优秀!