如何使用 gtest 对 std::bind 函数进行单元测试?
How to unit test the std::bind function using gtest?
我正在尝试为我项目中的一些 cpp 文件编写单元测试用例。
这里的场景是:
我有一个 cpp 文件,其中只定义了一个 public 方法,然后调用私有方法。
这里在public方法中调用私有方法作为回调方法。我如何在这里测试私有方法。我将对回调指针进行模拟,但我不确定如何调用私有方法。
请给我一些建议如何在这种情况下调用私有方法而不更改源代码。
这是前任:
buttonListenerList <<
sourceButton->addButtonActionCallback(std::bind(&AudioSource::buttonCallback, this, _1, _2));
这段代码是在 public 方法中定义的。现在 AudioSource::buttonCallback
是一个私有方法。你如何确保通过调用public方法来调用这个私有方法。
在单元测试中,您不测试私有成员函数,只测试 public 个。
我有一个大型项目,它使用 map
和一个 function
的列表,这些列表绑定了参数。我用不同的参数调用 public 方法,这些参数又调用地图中的各种函数。然后我可以检查响应状态(错误代码,因为这是多线程的)以验证正确的行为。这是你在你的场景中应该做的。
调用public函数,检查最后的状态。
如果,(您在评论中回答是)sourceButton
可以被模拟 - 然后调用 expect addButtonActionCallback
- 并存储传递的 std::function<>
arg。
就像下面的例子(用真实类型替换...):
struct TestSuite : public ::testing::Test {
... sourceButtonMock;
std::unique_ptr<...> objectUnderTest;
void SetUp() override;
std::function<...> sourceButtonActionCallback;
};
using namespace ::testing;
void TestSuite::SetUp()
{
EXPECT_CALL(sourceButtonMock, addButtonActionCallback(_))
.WillOnce(SaveArg<0>(&sourceButtonActionCallback);
objectUnderTest = std::make_unique<...>(sourceButtonMock);
}
已将此回调存储在 sourceButtonActionCallback
成员变量中 - 您可以在任何地方自由调用它:
TEST_F(TestSuite, shallDo...OnSourceButtonClick)
{
// prerequisites
ASSERT_NE(sourceButtonActionCallback, nullptr);
// Expecteations
...
// action
sourceButtonActionCallback(...);
// post-assertions
...
}
我认为你必须考虑你想要测试什么。
- 如果你想测试按下按钮时是否会调用回调,你不需要暴露你的私有方法,事实上你不需要这样做,因为按钮"is already proven".按下按钮时,将调用关联的回调。
- 如果你想测试你的私有函数是否做了他们应该做的事情,回调的结果应该修改一些状态(可以通过 getters 公开)。然后您需要一种调用按钮事件的方法,或者您可以使用可以通过按钮和测试公开的虚函数。
没有看到代码就很难进一步评论,但不要尝试测试按钮是否有效(调用回调)。没有意义。
因此,(私有)回调会在发生时修改状态。公开(不可变状态)并断言该状态符合预期。
我正在尝试为我项目中的一些 cpp 文件编写单元测试用例。
这里的场景是: 我有一个 cpp 文件,其中只定义了一个 public 方法,然后调用私有方法。
这里在public方法中调用私有方法作为回调方法。我如何在这里测试私有方法。我将对回调指针进行模拟,但我不确定如何调用私有方法。
请给我一些建议如何在这种情况下调用私有方法而不更改源代码。
这是前任:
buttonListenerList <<
sourceButton->addButtonActionCallback(std::bind(&AudioSource::buttonCallback, this, _1, _2));
这段代码是在 public 方法中定义的。现在 AudioSource::buttonCallback
是一个私有方法。你如何确保通过调用public方法来调用这个私有方法。
在单元测试中,您不测试私有成员函数,只测试 public 个。
我有一个大型项目,它使用 map
和一个 function
的列表,这些列表绑定了参数。我用不同的参数调用 public 方法,这些参数又调用地图中的各种函数。然后我可以检查响应状态(错误代码,因为这是多线程的)以验证正确的行为。这是你在你的场景中应该做的。
调用public函数,检查最后的状态。
如果,(您在评论中回答是)sourceButton
可以被模拟 - 然后调用 expect addButtonActionCallback
- 并存储传递的 std::function<>
arg。
就像下面的例子(用真实类型替换...):
struct TestSuite : public ::testing::Test {
... sourceButtonMock;
std::unique_ptr<...> objectUnderTest;
void SetUp() override;
std::function<...> sourceButtonActionCallback;
};
using namespace ::testing;
void TestSuite::SetUp()
{
EXPECT_CALL(sourceButtonMock, addButtonActionCallback(_))
.WillOnce(SaveArg<0>(&sourceButtonActionCallback);
objectUnderTest = std::make_unique<...>(sourceButtonMock);
}
已将此回调存储在 sourceButtonActionCallback
成员变量中 - 您可以在任何地方自由调用它:
TEST_F(TestSuite, shallDo...OnSourceButtonClick)
{
// prerequisites
ASSERT_NE(sourceButtonActionCallback, nullptr);
// Expecteations
...
// action
sourceButtonActionCallback(...);
// post-assertions
...
}
我认为你必须考虑你想要测试什么。
- 如果你想测试按下按钮时是否会调用回调,你不需要暴露你的私有方法,事实上你不需要这样做,因为按钮"is already proven".按下按钮时,将调用关联的回调。
- 如果你想测试你的私有函数是否做了他们应该做的事情,回调的结果应该修改一些状态(可以通过 getters 公开)。然后您需要一种调用按钮事件的方法,或者您可以使用可以通过按钮和测试公开的虚函数。
没有看到代码就很难进一步评论,但不要尝试测试按钮是否有效(调用回调)。没有意义。
因此,(私有)回调会在发生时修改状态。公开(不可变状态)并断言该状态符合预期。