GMock: Match the address of EXPECT_CALL parameter - c++

Is there a way to match the address of a given parameter in an EXPECT_CALL?
I have code like the following:
EXPECT_CALL(mock1, GetTheData()).WillOnce(Return(theData));
EXPECT_CALL(mock2, SetTheData(_)); // How to check the parameter is the same object as the one returned by GetTheData
// the following was tried but does not work
EXPECT_CALL(mock2, SetTheData(_)).WillOnce([&theData](auto param){ EXPECT_EQ(&theData, param) })
But because the SetTheData function takes its argument by value, the address is different. So I would need to find a way to get the object, before it was passed to the SetTheData function.
I tried some stuff with matches, but that did not seem to work either.
Is this possible at all? If so, how? And if not, why not?
EDIT:
As requested here is a more complete example to give more context.
struct TheData
{
// some stl containers
std::unordered_map<int, std::array<std::byte, 16>> mapToArrays;
std::unordered_map<int, long long> mapToInts;
}
class IDataFetcher
{
public:
virtual TheData GetTheData() = 0;
}
class IDataReceiver
{
public:
virtual void SetTheData(TheData theData) = 0;
}
class DataFetcherMock : public IDataFetcher
{
public:
MOCK_METHOD(TheData, GetTheData, (), (override));
}
class DataReceiverMock
{
public:
MOCK_METHOD(void, SetTheData, (TheData), (override));
}
class Sut
{
public:
Sut(std::unique_ptr<IDataFetcher> fetcher, std::unique_ptr<IDataReceiver> receiver)
void DoTheThing()
{
mReceiver->SetTheData(mFetcher->GetTheData());
}
private:
std::unique_ptr<IDataFetcher> mFetcher;
std::unique_ptr<IDataReceiver> mReceiver;
}
TEST(TestFoo, TestGroupFoo)
{
auto fetcherMock = std::make_unique<DataFetcherMock>();
auto receiverMock = std::make_unique<DataReceiverMock>();
EXPECT_CALL(*fetcherMock, GetTheData()).WillOnce(Return(theData));
EXPECT_CALL(*receiverMock, SetTheData(_)); // Here I want to check the objects are the same
Sut sut(std::move(fetcherMock), std::move(receiverMock));
sut.DoTheThing();
}

Related

Return pointer to derived class from base class

I would like to now if the following is possible.
I have a templated class called A which inherits from a class called Base.
In Base I set a write() function to be rewritten for every derived class.
I am creating a vector to store the references of the Base objects to be printer latter (dataBase).
I would like to know if it is possible to retrieve the reference of the A object whose reference I passed to dataBase.
I have the following code:
#include <iostream>
#include <string>
#include <array>
#include <vector>
class Base
{
public:
Base(std::string name):name_(name){}
virtual ~Base(){}
virtual void write()=0;
const std::string& name() const
{
return name_;
}
private:
std::string name_;
};
template< typename T>
class A : public Base
{
public:
A(std::string name):Base(name),name2_(name + "test"){}
~A(){}
void write();
std::string name2_;
};
template< typename T>
void A<T>::write()
{
std::cout << name2_ << std::endl;
}
int main()
{
A<int> one("one");
A<double> two("two");
A<std::array<double,4>> three("three");
std::vector<Base*> dataBase;
dataBase.push_back(&one);
dataBase.push_back(&two);
dataBase.push_back(&three);
for(auto i : dataBase)
{
i->write();
}
A<int>& getOne = lookup("one"); // this is what I want to create
getOne.name2_ = "worked";
for(auto i : dataBase)
{
i->write();
}
return 0;
}
Best Regards
A<int>& lookup(std::vector<Base*> & dataBase, // need to provide database
const std::string & seeking)
{
// find a match
auto found = std::find_if(dataBase.begin(),
dataBase.end(),
[seeking](Base * item)
{
return item->name() == seeking;
});
if (found != dataBase.end())
{ // found it
// convert to A<int>
A<int> * temp = dynamic_cast<A<int>*>(*found);
if (temp) // dynamic_cast returns nullptr on failure.
{ // successful conversion
return *temp; // return it.
}
throw std::runtime_error("wrong type"); // What we found isn't the desired type
}
throw std::runtime_error("not found"); // Couldn't find a match
}
Note: when returning a reference, you need to return a reference to a valid object. You can't legally return a nullptr to signal failure, so instead we throw.
Usage:
A<int>& getOne = lookup(dataBase, "one");
getOne.name2_ = "worked";
If you
A<int>& getTwo = lookup(dataBase, "two");
getTwo.name2_ = "worked";
two will be found, but the type will not match and an A<int> & can't be returned. An exception will be thrown.
If you
A<int>& getFoo = lookup(dataBase, "foo");
getFoo.name2_ = "worked";
foo will not be be found and an A<int> & can't be returned. An exception will be thrown.
Note: using a dynamic_cast often means the base class interface is not sufficiently defined to make for a good base class. See the Liskov Substitution Principle for a good test to see whether nor not inheritance is a good choice to use here.
Documentation for std::find_if
Documentation for dynamic_cast

C++: Object Stores Lambda into a Struct and Later Calls that Function

What's the proper syntax to accomplish this? The idea is that some object of any class could store a lambda expression in class GuiButton, and then later that call that lambda expression with access to its own local variables.
It should be noted that my platform (Arduino) does NOT support the functional header.
The code I've written to try to express this idea (which does not compile due to the lambda expressions not having access to members of ExampleScreen):
struct GuiButton {
uint8_t x; //coordinates for displaying this GUI element
uint8_t y;
GuiButton(uint8_t _x, uint8_t _y, void (*_callback)()) :
x(_x),
y(_y),
callback(_callback)
{};
virtual void draw(bool _highlight);
public:
void (*callback)(); //to be executed BY THE PARENT OBJECT when this element is clicked
};
struct GuiTextButton: public GuiButton {
char* text; //text to display in this GUI element
GuiTextButton(uint8_t _x, uint8_t _y, char* _text, void (*_callback)()) :
GuiButton(_x, _y, _callback),
text(_text)
{};
void draw(bool _highlight);
};
class ExampleScreen{
private:
GuiButton** buttonPtr;
uint8_t buttonCount;
uint8_t selectedButton;
bool proc1Active;
bool proc2Active;
public:
ExampleScreen() :
buttonPtr(NULL),
buttonCount(0),
selectedButton(0),
proc1Active(false),
proc2Active(false)
{
//different derived classes of GuiScreen shall have different constructors to define
//their visual and functional elements
buttonPtr = new GuiButton* [2];
buttonCount = 2;
{
char text[] = "Button1";
GuiButton *_thisPtr = new GuiTextButton(5,0,text, []() {
proc1Active = ~proc1Active;
});
buttonPtr[0] = _thisPtr;
}
{
char text[] = "Button2";
GuiButton *_thisPtr = new GuiTextButton(5,0,text, []() {
proc2Active = ~proc2Active;
});
buttonPtr[2] = _thisPtr;
}
};
void click() {
void (*callback)() = (buttonPtr[selectedButton]->callback);
callback();
};
};
int main() {
ExampleScreen gui;
gui.click();
};
Something along these lines:
class GuiButton {
GuiButton(void (*_callback)(void*), void* _context)
: callback(_callback), context(_context) {}
// Invoke the callback as callback(context)
void (*callback)(void*);
void* context;
};
// In ExampleScreen
new GuiButton([](void* context) {
auto self = static_cast<ExampleScreen*>(context);
self->proc1Active = ~self->proc1Active;
}, this);
Per the comments on your discussion you can't use the functional header which rules out the easy solutions (namely having the callback be a std::function and either capturing the context or using std::bind to bind it.
However, I think you can still do what you want. Make the type of callback be a struct like:
struct CallbackData {
void (*callback)(ExampleScreen*);
ExampleScreen* context;
// obvious constructor here...
}
Then you can call the callback like so:
callback_data.callback(callback_data.context);
And you pass it to the GuiButton constructor like:
new GuiTextButton(5,0,text,CallbackData([](ExampleScreen* e) { ... }, this));
Perhaps a nicer option is to use a functor. To do that you'd create a class like so:
class GuiButtonCallback {
public:
GuiButtonCallback(ExampleScreen* context) : context_(context) {}
void operator() {
context->proc1Active = ~context->proc1Active;
}
private:
ExampleScreen* context_;
};
And then you can construct things like so:
new GuiTextButton(5 , 0, text, GuiButtonCallback(this));

STL Container for storing multiple types of values?

I have a Message structure that I am using with a message bus, and I'd like to send data with messages. The problem is that the data will vary in type; maybe for one message I'll just want to send one int, but for another I'll want to send several ints, a string, maybe even a pointer to an object for example. I could do something like this:
struct Message {
std::map<int, int> intPayload;
std::map<int, std::string> strPayload;
short id;
};
But not only is this ugly and unclean, and probably wastes space, but that doesn't account for if I want to pass a relatively exotic data type like a pointer to an instance of a class for example. What should I be using for this?
A simple example using inheritance and polymorphism:
struct MessageBase
{
// The function to send *this* message to the receiver
virtual void send(ReceiverClass*) = 0;
};
struct MessageInt : MessageBase
{
int payload;
void send(ReceiverClass* receiver)
{
// Code to send this message type to the receiver...
}
};
struct MessageString : MessageBase
{
std::string payload;
void send(ReceiverClass* receiver)
{
// Code to send this message type to the receiver...
}
};
// ...
// Vector to store the messages
std::vector<MessageBase*> messages;
// Add a couple of messages
messages.push_back(new MessageInt{123});
messages.push_back(new MessageString{"Foobar"});
// Send the message to some receiver
for (auto const* message : messages)
message->send(some_reciver_object);
Any good book should be able to give you more information.
You can base your solution on the visitor pattern.
As a minimal, working example:
struct Listener;
struct Message {
virtual void accept(Listener &) = 0;
};
struct SimpleMessage: Message {
void accept(Listener &) override;
int i;
};
struct ComplexMessage: Message {
void accept(Listener &) override;
int i;
char c;
double d;
};
struct Listener {
void visit(SimpleMessage &) {}
void visit(ComplexMessage &) {}
void listen(Message &m) { m.accept(*this); }
};
void SimpleMessage::accept(Listener &l) { l.visit(*this); }
void ComplexMessage::accept(Listener &l) { l.visit(*this); }
struct Bus {
Bus(Listener *l): l{l} {}
void publish(Message &m) { l->listen(m); }
private:
Listener *l;
};
int main() {
Listener l;
Bus b{&l};
SimpleMessage sm;
ComplexMessage cm;
b.publish(sm);
b.publish(cm);
}
Set aside the fact that the implementation for the Bus is trivial, note that visit member functions in Listener can be virtual.
This way, all your listener can be derived from that class and override the desired methods.
The Bus will accept a set of Listeners, no matter what's the actual derived type, and a generic Message. On the other side, message will promote itself to the right derived type and pass a reference to the given listener.
The technique behind the visitor pattern is also known as double dispatching, if you want to explore it further.
There are many ways to do this. Here's an example with C++17's std::variant:
std::vector<std::variant<int, std::string>> vec1;
vec1.emplace_back(1);
vec1.emplace_back("hello"s);
doSomethingWithInt( std::get<int>(vec1[0]) );
doSomethingWithString( std::get<std::string>(vec1[1]) );
vec1 is a list of element that are either int or std::string.
You can also use a static visitor:
std::vector<std::variant<int, std::string>> vec2;
// ...
for(auto&& variant : vec1) {
variant.visit([](auto value){
using t = decltype(value);
if constexpr (std::is_same_v<t, int>) {
std::cout << "value is a int!" << std::endl;
} else if constexpr (std::is_same_v<t, std::string>) {
std::cout << "value is a string!" << std::endl;
}
});
}

How to match argument reference in Google Mock

I am newer for google mock. Now I have one question about how to match the argument reference? here are the codes
class Parameter {
public:
int m_idata;
char m_cdata;
bool Parameter::operator ==(const Parameter& element) const {
return (m_idata == element.m_idata && m_cdata == element.m_cdata);
}
};
class FooInterface {
public:
virtual ~FooInterface() {}
virtual void SetParameter(Parameter& val) = 0;
};
// mock class
class MockFoo: public FooInterface {
public:
MOCK_METHOD1(SetParameter, void(Parameter& val));
};
TEST(FooTest, setParameterTest) {
MockFoo mockFoo;
EXPECT_CALL(mockFoo, SetParameter(An<Parameter&>())); // How to match argument reference???
Parameter para;
mockFoo.SetParameter(para); // there is an exception here, why???
}
and I also tried the following to match SetParameter():
Parameter test_para;
EXPECT_CALL(mockFoo, SetParameter(Ref(test_para)));
And
EXPECT_CALL(mockFoo, SetParameter(A<Parameter&>()));
And
Parameter test_para;
test_para.m_cdata = 'c';
test_para.m_idata = 10;
EXPECT_CALL(mockFoo, SetParameter(_)).WillOnce(::testing::SetArgReferee<0>(test_para));
Both those two codes can also cause exception...
Could any one tell me how to match the argument reference Parameter& in the function SetParameter()?
This was supposed to be a comment, but I don't have enough reputation.
The only error in your code is that you have a superfluous "Parameter::".
I tried to run the code and I didn't see any exception. It ran just fine.

How come a pointer to a derived class cannot be passed to a function expecting a reference to a pointer to the base class?

Sorry for the long title but I did want to be specific.
I expected the following code to work but it doesn't and I can't figure out why :/
#include <cstdio>
#include <cassert>
class UniquePointer
{
public:
void Dispose()
{
delete this;
}
friend void SafeDispose(UniquePointer*& p)
{
if (p != NULL)
{
p->Dispose();
p = NULL;
}
}
protected:
UniquePointer() { }
UniquePointer(const UniquePointer&) { }
virtual ~UniquePointer() { }
};
class Building : public UniquePointer
{
public:
Building()
: mType(0)
{}
void SetBuildingType(int type) { mType = type; }
int GetBuildingType() const { return mType; }
protected:
virtual ~Building() { }
int mType;
};
void Foo()
{
Building* b = new Building();
b->SetBuildingType(5);
int a = b->GetBuildingType();
SafeDispose(b); // error C2664: 'SafeDispose' : cannot convert parameter 1 from 'Building *' to 'UniquePointer *&'
b->Dispose();
}
int main(int argc, char* argv[])
{
Foo();
return 0;
}
Imagine it were legal. Then you could write code like this:
class Animal : public UniquePointer
{
};
void Transmogrify(UniquePointer*& p)
{
p = new Animal();
}
void Foo()
{
Building* b = nullptr;
Transmogrify(b);
b->SetBuildingType(0); // crash
}
Observe that you have violated the type system (you put an Animal where a Building should be) without requiring a cast or raising a compiler error.
I do not think that it is possible to make it work the way you have it designed. Instead, try the following:
template <typename T>
void SafeDispose(T * & p)
{
if (p != NULL)
{
p->Dispose();
p = NULL;
}
}
class UniquePointer
{
public:
void Dispose()
{
delete this;
}
protected:
UniquePointer() { }
UniquePointer(const UniquePointer&) { }
virtual ~UniquePointer() { }
};
It is not allowed because if it were you could do the following:
friend void SafeDispose(UniquePointer*& p)
{
p = new UniquePointer();
}
Building* building;
SafeDispose(building)
//building points to a UniquePointer not a Building.
I guess the work around would be a template function.
To answer the title of your question, you cannot bind a non-const reference to base to a derived class instance because you could then set that reference to a pointer to a base instance that isn't a derived. Consider this function:
void Renew(UniquePointer *& p) {
delete p;
p = new UniquePointer();
}
if you could pass it a pointer to Building you would be able to set it incorrectly to point to a UniquePointer instance.
As it has already been suggested the solution is to change your reference to a plain pointer. Not only this solves your problem, but it is also a better implementation of SafeDispose(); as you wrote it this function gave the false idea that you would always set to 0 all your UniquePointer instances. But what would happen if somebody wrote (assuming UniquePointer constructor was public for simplicity):
UniquePointer *p1 = new UniquePointer();
UniquePointer *p2 = p1;
SafeDispose(p1);
They would expect all of their UniquePointers to be properly taken care of, when p2 is actually invalid.
I guess your SafeDispose should probably look more like :
friend void SafeDispose(UniquePointer** p) ...
In order to invoke it using
SafeDispose(&(UniquePointer*)b);
Then it should work this way.
But your next statement
b->Dispose();
will break cause b should now be NULL, cause it has been disposed and set to NULL by your SafeDispose method.