【问题标题】:gmock EXPECT_CALL to both return and assign a value to one of the parametersgmock EXPECT_CALL 以返回并为参数之一赋值
【发布时间】:2022-07-27 00:06:07
【问题描述】:

我正在尝试使用 gmock 设置一个模拟,不仅可以返回一个值,还可以填充一个缓冲区。要模拟的函数的行为类似于 posix read(),因为它需要一个 void* 和一个大小,并将填充数据。

我正在尝试组合一个操作来执行此操作,但找不到有效的示例。我发现这方面的 gmock 文档有点稀缺。

有一个调用 ::testing::Invoke() 的答案,但我无法编译它。也许 gmock 已经改变了。那个答案是 9 岁:How to set GMock EXPECT_CALL to invoke two different functions for a mocked function

这是我的最小代码,显示了模拟的“getdata()”的调用。如何更改 EXPECT_CALL 行以填充 testdata[] 数组中的数据?

这是我的代码(由于缺少数据,编译并进行了失败的测试):

#include <gmock/gmock.h>

// The mock class
class MockDataSrc
{
public:
    MOCK_METHOD2(getdata,int(void *buf,int max));
};

// The Code-Under-Test:
class CUT{
public:
    CUT(MockDataSrc *s){m_s=s;}

    int getandadd()
    {
        unsigned char buf[32];
        unsigned int sum=0;
        int n;
        n=m_s->getdata(buf,sizeof(buf));
        for(int t=0;t<n;t++)sum+=buf[t];
        return (int)sum;
    }
private:
    MockDataSrc *m_s;
};

// The test class:
class Test_CUT : public ::testing::Test
{
public:
    Test_CUT(){source=nullptr;}

protected:
    void SetUp() override
    {
        source = new MockDataSrc();
    }

    void TearDown() override
    {
        delete source;
        source=nullptr;
    }

    MockDataSrc *source;

};

// The Test: Call getdata(), verify sum.
TEST_F(Test_CUT, TestGet)
{
    CUT cut(source);
    static const unsigned char testdata[]={13,21,29,37};

    // The expect-call here. How can I supply testdata[] in getdata()?
    EXPECT_CALL(*source,getdata(
            ::testing::NotNull(),::testing::Ge(4)
    )).WillOnce(::testing::Return(4));

    int sum;
    sum = cut.getandadd();
    EXPECT_EQ(sum,100);
}

【问题讨论】:

    标签: googlemock


    【解决方案1】:

    回复有点晚,但您可以使用DoAllSaveArgInvokeReturn 的组合来完成。

    基本上,为了响应getdata 调用,您执行以下操作:

    1. 使用SaveArg&lt;0&gt;保存buf指针。
    2. 使用通过调用 Invoke 调用的 lambda 将所需的值复制到 buf 指针中。
    3. 返回值 4。

    下面是完整的代码:

    #include <cstring>
    
    #include "gmock/gmock.h"
    #include "gtest/gtest.h"
    using ::testing::DoAll;
    using ::testing::Invoke;
    using ::testing::Return;
    using ::testing::SaveArg;
    
    // The mock class
    class MockDataSrc {
     public:
      MOCK_METHOD(int, getdata, (void *, int), ());
    };
    
    // The Code-Under-Test:
    class CUT {
     public:
      CUT(MockDataSrc *s) { m_s = s; }
    
      int getandadd() {
        unsigned char buf[32];
        unsigned int sum = 0;
        int n;
        n = m_s->getdata(buf, sizeof(buf));
        for (int t = 0; t < n; t++) {
          sum += buf[t];
        }
        return (int)sum;
      }
    
     private:
      MockDataSrc *m_s;
    };
    
    // The test class:
    class Test_CUT : public ::testing::Test {
     public:
      Test_CUT() { source = nullptr; }
    
     protected:
      void SetUp() override { source = new MockDataSrc(); }
    
      void TearDown() override {
        delete source;
        source = nullptr;
      }
    
      MockDataSrc *source;
    };
    
    // The Test: Call getdata(), verify sum.
    TEST_F(Test_CUT, TestGet) {
      MockDataSrc mock_source;
      CUT cut(&mock_source);
      void *buf;
    
      static const unsigned char testdata[] = {13, 21, 29, 37};
    
      // The expect-call here. How can I supply testdata[] in getdata()?
      EXPECT_CALL(mock_source, getdata(::testing::NotNull(), ::testing::Ge(4)))
          .Times(1)
          .WillOnce(DoAll(SaveArg<0>(&buf),
                          Invoke([&buf]() { std::memcpy(buf, testdata, 4); }),
                          Return(4)));
    
      int sum;
      sum = cut.getandadd();
      EXPECT_EQ(sum, 100);
    }
    

    这是一个工作示例:https://godbolt.org/z/zobW6arG5

    请参阅 GoogleTest 文档中的 this part

    【讨论】:

      猜你喜欢
      • 2016-04-25
      • 1970-01-01
      • 2018-12-30
      • 1970-01-01
      • 1970-01-01
      • 2022-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多