问题
I am trying to write unittest cases for some of the cpp files in my project.
The scenario here is: I have a cpp file with only one public method defined and in turn which calls private methods.
Here the private methods are called in the public method as a callback method. How do I test the private methods here. I will be doing the mocking for Callback pointer and I am not sure how to call the private method.
Please give me some suggestions how to call the private methods in this scenario without changing the source code.
Here is the ex:
buttonListenerList <<
sourceButton->addButtonActionCallback(std::bind(&AudioSource::buttonCallback, this, _1, _2));
This peace of code is defined in the public method. Now the AudioSource::buttonCallback
is a private method. How do you make sure to call this private method by calling the public method.
回答1:
If, (you answered yes in comment) sourceButton
can be mocked - then expect addButtonActionCallback
is called - and store the passed std::function<>
arg.
Like in the example below (replace ... with real types):
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);
}
Having stored this callback in sourceButtonActionCallback
member variable - you can call it freely wherever you wish:
TEST_F(TestSuite, shallDo...OnSourceButtonClick)
{
// prerequisites
ASSERT_NE(sourceButtonActionCallback, nullptr);
// Expecteations
...
// action
sourceButtonActionCallback(...);
// post-assertions
...
}
回答2:
In Unit Testing you do not test the private member functions, just the public ones.
I have a large project that uses a map
with a list of function
s that have parameters bound to them. I call the public method with different parameters which in turn calls various functions in the map. I can then inspect the response states (error codes as this is multi-threaded) to verify the correct behaviour. This is what you should do in your scenario.
Call the public function and inspect the state at the end.
回答3:
I think you have to consider what you want tested.
- If you want to test whether the callbacks will be called when the button is pushed, you needn't expose your private methods, in fact, you don't need to do that, as the button "is already proven". When the button is pressed, associated callbacks are called.
- If you want to test whether your private functions do what they should, the outcome of the callback should modify some state (which can be exposed via getters). Then you need a way to invoke the button event, or you could use a virtual function that can be exposed via button and test.
Without seeing the code it's hard to comment further, but don't try and test if the button works (calls a callback). No point there.
Therefore, the (private) callbacks modify state when they happen. Expose (the immutable state) and assert that the state is as expected.
来源:https://stackoverflow.com/questions/37591112/how-to-unit-test-the-stdbind-function-using-gtest