【问题标题】:How to write a test case for module dependent function using EXPECT_CALL in Google test?如何在 Google 测试中使用 EXPECT_CALL 为模块相关函数编写测试用例?
【发布时间】:2021-08-26 15:34:36
【问题描述】:

我是谷歌测试环境的新手。我有一个用 C 编写的示例代码,想用 Google 测试框架执行单元测试。

下面是示例代码

// My module function (test.c)

void Update_user_value(void)
{
    int user_value;
    user_value = get_val_module(); /* return a integer value*/

    if(user_value == 0x1)
      update_user_flag(true);
    else
      update_user_flag(false);  
}

// This function is in the other module(stub.c) , so we can use Mock function

void update_user_flag(bool val)
{
    struct *temp;

    if(val == true)
    {
        temp->userflag = 1;
    }
    else
    {
        temp->userflag = 0;
    }
}

我想为Update_user_value 函数编写一个测试用例(仅用于test.c)。通过这个函数,我将一些标志值发送到其他模块(update_user_flag)来设置标志。

我已经写了一个这样的简单谷歌测试

    TEST_F(sampletest, setuser_flag_true_testcase)
    {
        //Get value from module
        ON_CALL(*ptr1, get_val_module()).WillByDefault(Return(0x1)); //Mock function
    
        EXPECT_CALL(*ptr2, get_val_module(_)).Times(1); // Mock function

        Update_user_value();
    }

    TEST_F(sampletest, setuser_flag_false_testcase)
    {
        //Get value from module
        ON_CALL(*ptr1, get_val_module()).WillByDefault(Return(0x0)); //Mock function
    
        EXPECT_CALL(*ptr2, get_val_module(_)).Times(1); // Mock function

        Update_user_value();
    }

我的问题:这个测试用例是否足以验证Update_user_value 函数? 我也想知道,EXPECT_CALL() 是否适合用于为其他模块设置值? 如果我的理解有误,请给我推荐一个更好的测试用例?

【问题讨论】:

    标签: c++ c unit-testing googletest googlemock


    【解决方案1】:

    ON_CALLEXPECT_CALL 是设计用于模拟对象的宏。通常用例如下:

    1. 您创建一个从中派生的接口(它将在您的测试中被模拟)。
    2. 您将模拟对象传递给方法或通过依赖注入。
    3. 您对这个对象抱有期望。

    查看示例:

    class Foo {
    public:
        virtual ~Foo() = default;
    
        virtual int bar() = 0;
    };
    
    class FooMock : public Foo {
    public:
        MOCK_METHOD0(bar, int());
    };
    
    bool check_bar_over_42(Foo& foo) {
        if (foo.bar() > 42) {
            return true;
        }
        return false;
    }
    
    TEST(check_bar_over_42_test, bar_below_42) {
        FooMock fooMock{};
    
        EXPECT_CALL(fooMock, bar()).WillOnce(testing::Return(41));
    
        ASSERT_FALSE(check_bar_over_42(fooMock));
    }
    
    TEST(check_bar_over_42_test, bar_above_42) {
        FooMock fooMock{};
    
        EXPECT_CALL(fooMock, bar()).WillOnce(testing::Return(43));
    
        ASSERT_TRUE(check_bar_over_42(fooMock));
    }
    

    AFAIK 无法在类 C 函数上使用 EXPECT_CALLs。解决您的问题的一种方法是链接时模拟:给定方法 get_val_module 在单独的库中定义,您可以使用 get_val_module 创建仅测试库,这将允许您返回预期值。在测试中,您将链接到测试库,在生产中 - 链接到真正的库。

    【讨论】:

      猜你喜欢
      • 2012-10-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-24
      • 2019-10-01
      • 2012-03-23
      • 1970-01-01
      相关资源
      最近更新 更多