使用GTest/GMock测试含shared_ptr<FactoryClass>的C++ toString函数
Hey there! Since you're new to GTest/GMock and just need valid instances of those two pointers to test your toString() function without getting tangled up in the FactoryClass's messy logic and callbacks, here's a straightforward, no-fuss approach you can take:
The key here is to skip the FactoryClass entirely—you don't need it for this test. All you care about is having valid m_propBsh_p and m_eBsh_p instances to verify that toString() works as expected. Here's how to do it:
Step 1: Create Mock Classes for the Pointer Targets
First, assume your two pointers are of type shared_ptr<Bsh> (swap Bsh with whatever actual class they point to). Make a mock version of that class to use in tests:
#include <gmock/gmock.h> // Mock the class that m_propBsh_p and m_eBsh_p point to class MockBsh : public Bsh { public: // Mock any methods that your toString() function calls on these objects // For example, if toString() uses a getDetails() method: MOCK_METHOD(std::string, getDetails, (), (const, override)); // Add other mocked methods as needed based on your actual code };
Step 2: Inject the Mock Instances Into Your Test Class
If the Members Are Public
If m_propBsh_p and m_eBsh_p are public, you can just assign them directly in your test:
TEST(YourClassTest, ToStringProducesExpectedOutput) { // Create mock instances auto mockPropBsh = std::make_shared<MockBsh>(); auto mockEBsh = std::make_shared<MockBsh>(); // Set up expected behavior for the mock methods (if needed) EXPECT_CALL(*mockPropBsh, getDetails()) .WillOnce(testing::Return("Property BSH Data")); EXPECT_CALL(*mockEBsh, getDetails()) .WillOnce(testing::Return("E BSH Data")); // Initialize your class under test YourClass testObj; // Assign the mock pointers directly testObj.m_propBsh_p = mockPropBsh; testObj.m_eBsh_p = mockEBsh; // Test the toString() method std::string result = testObj.toString(); EXPECT_THAT(result, testing::HasSubstr("Property BSH Data")); EXPECT_THAT(result, testing::HasSubstr("E BSH Data")); }
If the Members Are Private
No problem—you have two easy options:
Make the test class a friend
Add this to yourYourClassheader (wrap it in a test-only macro to keep production code clean):#ifdef TEST_BUILD friend class YourClassTest; // Match your test case class name #endifNow your test code can access the private members directly, just like the public case above.
Add a test-only initialization method
Add a method toYourClassthat's only compiled for tests, letting you inject the pointers:#ifdef TEST_BUILD void injectBshInstances(std::shared_ptr<Bsh> propBsh, std::shared_ptr<Bsh> eBsh) { m_propBsh_p = propBsh; m_eBsh_p = eBsh; } #endifThen in your test, call
testObj.injectBshInstances(mockPropBsh, mockEBsh)instead of assigning directly.
Why Skip Mocking the Factory?
Your goal is to test toString(), not the FactoryClass or how it creates these instances. By mocking the direct dependencies (Bsh objects) and injecting them, you keep your test focused on the behavior you care about—no need to waste time replicating the factory's complex logic or callbacks. This makes your test simpler, faster, and easier to maintain.
内容的提问来源于stack exchange,提问作者Ali

