为啥 void * 指向 gmock 中的 SetArgPointee 的指针会导致错误

Posted

技术标签:

【中文标题】为啥 void * 指向 gmock 中的 SetArgPointee 的指针会导致错误【英文标题】:Why does void * pointer to SetArgPointee in gmock cause error为什么 void * 指向 gmock 中的 SetArgPointee 的指针会导致错误 【发布时间】:2020-06-12 02:08:33 【问题描述】:

考虑一下:

struct INFO 
  unsigned char a;
  int b;
  char c[100];
;
...
INFO inf = 'X', 1010, "AOK Message";
void *mdptr_s = reinterpret_cast<void *>(&inf);
size_t msiz1 = sizeof(inf);

模拟是:

MOCK_METHOD((size_t), recv, (void *buf_, size_t len_), (override));

在我的模拟测试中有一个EXPECT_CALL 使用:

.WillRepeatedly(DoAll(
SetArgPointee<0>(mdptr_s), Return(msiz1)));

为什么会导致错误?

/usr/local/include/gmock/gmock-actions.h:780:5: 错误:‘void*’不是指向对象的指针类型 *::std::get(std::tie(args...)) = 值; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

相关的gmock代码为:

// Implements the SetArgumentPointee<N>(x) action for any function
// whose N-th argument (0-based) is a pointer to x's type.
template <size_t N, typename A, typename = void>
struct SetArgumentPointeeAction 
  A value;

  template <typename... Args>
  void operator()(const Args&... args) const 
    *::std::get<N>(std::tie(args...)) = value;
  
;

完整代码

mock_turtle_test.cc

#include "mock_turtle.h"
#include "painter.h"
#include <gtest/gtest.h>

using  ::testing::_;
using  ::testing::AtLeast;
using  ::testing::Return;
using  ::testing::DoAll;
using  ::testing::SetArgPointee;

struct INFO 
  unsigned char a;
  int b;
  char c[100];
;

TEST(PainterTest, CanDrawSomething) 
    INFO inf = 'X', 1010, "AOK Message";
    INFO spl_dat;
    size_t msiz1 = sizeof(inf);
    void *mdptr_s = reinterpret_cast<void *>(&inf);
    Painter painter;
    EXPECT_CALL(*painter.turtle, setSpecial(_,_))
        .Times(AtLeast(1))
        .WillRepeatedly(DoAll(
            SetArgPointee<0>(mdptr_s), Return(msiz1)));
    EXPECT_TRUE(painter.callSpecial(&spl_dat));


int main(int argc, char **argv) 
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();

mock_turtle.h

#pragma once
#include <cstdlib>
#include <gmock/gmock.h>

class FakeTurtle 

public:
  virtual ~FakeTurtle() 
  virtual int setSpecial(void* buf, size_t len);
;

class Turtle : public FakeTurtle
 public:
  using FakeTurtle::FakeTurtle;
  MOCK_METHOD((int), setSpecial, (void *buf, size_t len),(override));
;

画家.h

#pragma once

class Painter

public:
    Turtle* turtle;
    Painter() : turtle(new Turtle)
    Turtle** getTurtle()
        return &turtle;
    
    template <typename T>
    int callSpecial(T *buf)
        void *dptr = reinterpret_cast<void *>(buf);
        size_t sz = sizeof(T);
        return turtle->setSpecial(dptr, sz);
    
    ~Painter()
        if(turtle != NULL)
            delete turtle;
    
;

CMakeLists.txt

cmake_minimum_required(VERSION 2.6)

# Locate GTest
find_package(GTest REQUIRED)
find_package(PkgConfig)
message(STATUS "gtest found: " $GTEST_FOUND)
pkg_check_modules(GMOCK "gmock" REQUIRED)
message(STATUS "gmock found: " $GMOCK_FOUND)

include_directories($GTEST_INCLUDE_DIRS)

# Link runTests with what we want to test and the GTest and pthread library
add_executable(runTests mock_turtle_test.cc)
target_link_libraries(runTests $GTEST_LIBRARIES $GMOCK_LIBRARIES gmock gmock_main gtest gtest_main)
add_test(NAME runTests COMMAND runTests)
enable_testing()

【问题讨论】:

这有帮助吗:groups.google.com/forum/#!topic/googlemock/sWBP2q8VZaA 它确实有帮助。你能把它写进答案吗? 好的,不过如果你认为你可以为 Stack Overflow 写一个更有用的答案,那就太棒了(我个人不熟悉 google mock) 【参考方案1】:

在另一个线程上询问并回答了类似的问题,也许这会有所帮助:https://groups.google.com/forum/#!topic/googlemock/sWBP2q8VZaA

【讨论】:

以上是关于为啥 void * 指向 gmock 中的 SetArgPointee 的指针会导致错误的主要内容,如果未能解决你的问题,请参考以下文章

GMock:在模拟函数中捕获引用参数

C++ 从 void* 中恢复指向未知关联容器的元素

为啥指向成员函数的指针不像数据指针那样只是内存地址

如何使用 gmock 模拟修改 C++ 类中的私有变量的成员函数?

GoogleTest中gMock的使用

为啥 C++11 包含一个关于比较 void 指针的奇怪子句?