简体   繁体   中英

How to test the sequence of function calls in C?

I'm using Gtest to perform unit testing to a C module. One of the requirements is to verify that a function called Supervision_Log() is called after executing several different functions. The C file includes the following:

void MainFunction (void)
{
    .
    .
    .
    /*Some code*/
    .
    .
    .
    ModeMonitoring();
    RadarStatusMonitoring();
    CameraStatusMonitoring();
    Supervision_Log(ModeManager);
}

I came to know that there's a facility in CppUTest called mock().strictOrder() that does what I need. But, is there any similar thing like that in Gtest? or what shall I do?

PS: We need to put a test case that fails if anyone changed the order of function calls. This test case will act as a guardian to this order against any changes in future releases.

对于单元测试,您应该使用gcov代码覆盖率实用程序,它告诉您代码中哪个部分没有执行,还提供了有关给定函数被调用多少次的报告,但是您需要使用代码覆盖率标记来构建代码

  1. You have to change code under test so you can inject dependency. This can be done by static or dynamic polymorphism (I usually do a mix, but for simplicity lets do dynamic polymorphism):
class IDependency {
public:
    virtual ~IDependency() {}

    virtual void ModeMonitoring() = 0;
    virtual void RadarStatusMonitoring() = 0;
    virtual void CameraStatusMonitoring() = 0;
    virtual void Supervision_Log(const ModeManagerType&) = 0;
};

class ProductionDependency : public IDependency {
public:
    void ModeMonitoring() override {
       ::ModeMonitoring();
    }

    void RadarStatusMonitoring() override {
       ::RadarStatusMonitoring();
    }
    void CameraStatusMonitoring() override {
       ::CameraStatusMonitoring();
    }
    void Supervision_Log(const ModeManagerType& x) override {
       ::Supervision_Log(x);
    }
};

ProductionDependency productionDependency;

void MainFunction(IDependency& dep = productionDependency)
{
    // ....
    dep.ModeMonitoring();
    dep.RadarStatusMonitoring();
    dep.CameraStatusMonitoring();
    dep.Supervision_Log(ModeManager);
}
  1. Then in test provide a mock for dependency:
class MockDependency : public IDependency {
public:
    MOCK_METHOD(void, ModeMonitoring, (), (override));
    MOCK_METHOD(void, RadarStatusMonitoring, (), (override));
    MOCK_METHOD(void, CameraStatusMonitoring, (), (override));
    MOCK_METHOD(void, Supervision_Log, (const ModeManagerType&), (override));
};
  1. Finally in a test express required order:
TEST(MainFunction, callsInOrder)
{
    MockDependency dep;

    Expectation modeMonitoring = EXPECT_CALL(dep, ModeMonitoring());
    EXPECT_CALL(dep, CameraStatusMonitoring()).After(modeMonitoring); // here order is forced

    EXPECT_CALL(dep, RadarStatusMonitoring());
    EXPECT_CALL(dep, Supervision_Log(_));

    MainFunction(dep);
}

Here is doc about After .

Please do not specify to strict order. Make sure only required order is limited by test, for example order required by external API. Do not specify order of all calls based on current implementation, since this will limit your refactoring opportunities.

Here is live demo .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM