-1

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?

P.S.: 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.

273K
  • 29,503
  • 10
  • 41
  • 64
Mohamed Ameen
  • 65
  • 1
  • 8

2 Answers2

0

For unit testing you should use gcov code coverage utility, it tells you which part of code executed which did not, it also provides report on how many times a given function is called, but you need to build your code with code coverage flag

Pras
  • 4,047
  • 10
  • 20
  • I'm already using gcov for coverage, but we need a test case that fails if the order of the function calls changed in the future. @Pras – Mohamed Ameen Apr 28 '17 at 15:55
0
  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.

Marek R
  • 32,568
  • 6
  • 55
  • 140