Reputation: 1587
Consider this:
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);
The mock is:
MOCK_METHOD((size_t), recv, (void *buf_, size_t len_), (override));
In my mock test there is an EXPECT_CALL
using:
.WillRepeatedly(DoAll(
SetArgPointee<0>(mdptr_s), Return(msiz1)));
Why does this cause an error?
/usr/local/include/gmock/gmock-actions.h:780:5: error: ‘void*’ is not a pointer-to-object type *::std::get(std::tie(args...)) = value; ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The relevant gmock code is:
// 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;
}
};
Full Code
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));
};
painter.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()
Upvotes: 1
Views: 3739
Reputation: 141618
There was a similar problem asked and answered on this other thread, perhaps that will help: https://groups.google.com/forum/#!topic/googlemock/sWBP2q8VZaA
The idea is basically to use custom actions like ACTION_P as the default handling doesn't allow void pointers to be assigned as you are trying to achieve.
Upvotes: 1