我正在使用gtest和gmock框架进行单元测试,我需要在存入/模拟在类函数内部使用的外部C函数方面提供帮助

问题描述 投票:1回答:2

因此,我试图为我的生产代码编写测试用例,但是由于使用了一些外部C库,如果没有目标硬件,这些C库就无法执行,因此覆盖率非常低,因此我只能选择将其存根。现在的问题是如何对C函数存根?

我的生产代码:prod_code.cpp

 int TargetTestClass::targetFunc()
 {
    if(externalCFunc() == True)
    {
        statement1; statement2; statement3; /// and so on
    }
 }

我的testcode.cpp通常包含这样的测试

//Fixture for Target Test class
class TargetTestClassFixture : public testing::Test {
      TargetTestClass* targetTestClassPtr;
      void SetUp() {
         targetTestClassPtr = new TargetTestClass();
      }
      void TearDown() {
         delete targetTestClassPtr;
      }
  };



TEST_F (unitTest, test_001)
  {
       targetTestClassPtr->targetFunc(); //Need to do something here so that externalCFunc() returns true on call
  }
c++ unit-testing googletest gmock
2个回答
1
投票

您可以做的是创建一个像my_c_stubs.c这样的源文件,您可以在其中初步实现C函数。例如,实现可以只返回true。然后,不要将原始源文件与外部C函数链接,而要使用存根文件。您仍应使用原始的C标头。这样,您将无法使用内联函数。如果需要,则需要一些更复杂的方法。


0
投票

//我找到了2个解决问题的方法,所以我将在此处回答同样的问题,并关闭此问题:

//解决方案1:这涉及更改目标源代码。//基本上,您需要编写一个包装程序,以调用外部C函数,如下所示

Class TargetTestClass{
    protected:
        int targetFunc();
        virtual int externalCFuncWrapper();  // Wrapper
};

//call the external C function from the wrapper
int TargetTestClass::externalCFunctionWrapper(){
    return(externalCFunc());
}

//Definition of targetFuc in original question

//Now write a mock class for Target Test Class as usual and mock the wrapper function to return what you want to 

class MockTargetTestClass : public TargetTestClass{
    public: MOCK_METHOD0(externalCFunctionWrapper, int());
};

//Now use the Mock class as needed
TEST_F ( TargetUnitTest, TestingExternalCFuctionCall)
{
    MockTargetTestClass mockTargetTestClassObj;
    using ::testing::Return;
    using ::testing::_;
    Expect_Call(mockTargetTestClassObj, externalCFunctionWrapper())
    .WillOnce(Return(1));

    Assert_EQ(mockTargetTestClassObj.targetFunc(), 1);
}

//Solution 2 : Thanks to @kreynolds, I have looked into Fake Function Framework and implemented as follows : 

Class TargetTestClass{
    protected:
        int targetFunc();
        //No Code change needed in target source code
};

//In testcode.cpp 

#include <gmock-global/gmock-global.h>

MOCK_GLOBAL_FUNC0(externalCFunc, int());

TEST( Unittest, test002){
    using ::testing::Return;
    using ::testing::_;
    EXPECT_GLOBAL_CALL(externalCFunc, externalCFunc()).WillOnce(Return(1));

    TargetTestClass targetFunc; //This does not contain any wrapper
    EXPECT_EQ(targetTestClassObj.targetFunc(), 1);
}


//I am using the second solution as this does not require any change in my source code and easier to use.


//Once again thank you everyone for giving your time.
© www.soinside.com 2019 - 2024. All rights reserved.