如何编写谷歌模拟匹配器来匹配空指针参数?

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

我有一个函数需要一个我正在嘲笑的 const void* 。我想要基于传递到函数中的指针值的匹配器。

例如:

#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"


class A
{
    public:
        A(std::vector<uint32_t> data) : m_data(data) {}
        void doSomething()
        {
            for (auto x : data)
                writeData(&x, sizeof(x))
                
        }
        void writeData(const void* val, size_t size)
        {
            //More complicated than that obviously
            std::cout << "Writing data" << std::endl;
        }
    private:
        std::vector<uint32_t> m_data;
    
};


class MockA : public A
{
    public: 
        MOCK_METHOD(void, writeData, (const void* val, size_t size));
        
}


TEST(TestA, writeData)
{
    std::vector<uint32_t> testData{1,2,3,4};
    MockA myMockObj (testData);
    
    uint32_t expVal1 = 1;
    uint32_t expVal2 = 2;
    uint32_t expVal3 = 3;
    uint32_t expVal4 = 4;
    
    //The problem is the matcher won't work because writeData takes const void*
    //Pointer comparison doesn't work because the pointers dont't point to the same obj
    //for example &testData[1] != m_data[1] and also (void*)&expVal2 != val
    
    EXPECT_CALL(myMockObj, writeData(expVal4, 4)).Times(1);
    EXPECT_CALL(myMockObj, writeData(expVal3, 4)).Times(1);
    EXPECT_CALL(myMockObj, writeData(expVal2, 4)).Times(1);
    EXPECT_CALL(myMockObj, writeData(expVal1, 4)).Times(1);
    
    
    
    
    myMockObj.doSomething();
}

我想要一个根据两个参数的值进行匹配的匹配器,如上例所示。 问题是第一个参数是 void* 而不是 uint32_t。

我无法进行指针比较,因为参数和我要匹配的内容位于不同的内存位置。

我发现这个讨论这似乎表明我将无法使用 SaveArgPointee 副作用。我确实尝试了一些类似的事情:

uint32_t testData = 50;
uint32_t actualData;
EXPECT_CALL(myMockObj, writeData(testing::_, 4)).Times(1).WillOnce(testing::SaveArgPontee<0>(&actualData));

抱怨

const void* is not a pointer-to-oject type

然后我尝试像这样写我自己的动作

ACITON_P(AssignVoidPtr, param) {param = * (const_cast<uint32_t*>(static_cast<const unit32_t*>(arg0))); }

才发现参数不可写

我尝试使用间接方法,通过另一个自定义操作返回指针的值:

ACITON(AssignVoidPtr) { return * (const_cast<uint32_t*>(static_cast<const unit32_t*>(arg0))); }

class MockA : public A
{
    public: 
        MOCK_METHOD(uint32_t, dummy, (const void* val, size_t size));
        
        void writeData(conts void* val, size_t size)
        {
            dummy(val, size)
        }
        
        
}


TEST(TestA, writeData)
{
    std::vector<uint32_t> testData{1,2,3,4};
    MockA myMockObj (testData);
    
    uint32_t expVal1 = 1;
    uint32_t expVal2 = 2;
    uint32_t expVal3 = 3;
    uint32_t expVal4 = 4;
    
    uint32_t actVal1;
    uint32_t actVal2;
    uint32_t actVal3;
    uint32_t actVal4;
    
    //In the actual test I can differentiate between the expect calls so the correct value is assigned to each var
    actVal4 = EXPECT_CALL(myMockObj, dummy(testing::_, 4)).Times(4).WillOnce(AssignVoidPtr());
    actVal3 = EXPECT_CALL(myMockObj, dummy(testing::_, 4)).Times(1).WillOnce(AssignVoidPtr());
    actVal2 = EXPECT_CALL(myMockObj, dummy(testing::_, 4)).Times(1).WillOnce(AssignVoidPtr());
    actVal1 = EXPECT_CALL(myMockObj, dummy(testing::_, 4)).Times(1).WillOnce(AssignVoidPtr());
    
    ASSERT_EQ(data[0], actVal1);
    
    
    myMockObj.doSomething();
}

但是上面给出了一个错误,它无法在 fake_type 和 uint32_t 之间转换

知道如何实现这一目标吗?

c++ c++14 googlemock
1个回答
0
投票

修复了类定义中的一些编译器错误后,解决方案是:

#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"

class A {
 public:
  A(std::vector<uint32_t> data) : m_data(data) {}
  void doSomething() {
    for (auto x : m_data)
      writeData(&x, sizeof(x));
  }

  virtual void writeData(const void* val, size_t size) {}

 private:
  std::vector<uint32_t> m_data;
};

class MockA : public A {
 public:
  using A::A;
  MOCK_METHOD(void, writeData, (const void* val, size_t size), (override));
};

TEST(TestA, writeData) {
  using ::testing::Eq;
  using ::testing::Pointee;
  using ::testing::SafeMatcherCast;

  std::vector<uint32_t> testData{1, 2};
  MockA myMockObj(testData);

  EXPECT_CALL(myMockObj,
              writeData(MatcherCast<const void*>(
                            SafeMatcherCast<const uint32_t*>(Pointee(Eq(1)))),
                        sizeof(uint32_t)));
  EXPECT_CALL(myMockObj,
              writeData(MatcherCast<const void*>(
                            SafeMatcherCast<const uint32_t*>(Pointee(Eq(2)))),
                        sizeof(uint32_t)));

  myMockObj.doSomething();
}

https://godbolt.org/z/KxjrTeW84

© www.soinside.com 2019 - 2024. All rights reserved.