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.
Related
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
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();
}
I thing I'm missing something obvious but here is my problem
with a pure abstract class IFoo
class IFoo
{
public:
virtual bool isBar1() const=0;
virtual bool isBar2() const=0;
};
and 2 implementations
class Foo1 : public IFoo
{
public:
bool isBar1() const override { return true;}
bool isBar2() const override { return false;}
};
class Foo2 : public IFoo
{
public:
bool isBar1() const override { return false;}
bool isBar2() const override { return true;}
};
I have a managing class that must call the right method depending on a variable protocol
class FooManager : public IFoo
{
public:
bool isBar1() const override
{
switch(protocol)
{
case 1: return Foo1().isBar1();
case 2: return Foo2().isBar1();
default: return false;
}
}
bool isBar2() const override
{
switch(protocol)
{
case 1: return Foo1().isBar2();
case 2: return Foo2().isBar2();
default: return false;
}
}
void setProtocol(int proto){this->protocol = proto;}
private:
int protocol{0};
};
But there is a bunch of methods and I don't want to put the switch(protocol)everywhere given that it's really repetitive and new FooX could be added at anytime.
How can I call the right override without using templates (given that protocol is dynamic and FooManager is persistent)
and without using the heap on every call (through smart pointer or the likes because it's for an embedded project where we try to stay on the stack as much as possible).
I can't just create a getFoo() method that return IFoo because it's an abstract class
And I can't return an IFoo& neither because it would return a reference to a temporary.
IFoo& FooManager::getFoo()
{
switch(protocol)
{
case 1: return Foo1();
case 2:
default: return Foo2();
}
//return reference to temporary
}
What else can I do?
You could return a unique_ptr, such as
std::unique_ptr<IFoo> FooManager::getFoo() {
switch (protocol) {
case 1: return std::make_unique<Foo1>();
case 2:
default: return std::make_unique<Foo2>();
}
}
This would result in the data being a pointer and polymorphism being applied on calling the member functions
You can return a std::unique_ptr so you get polymorphic behavior but can control the lifetime of the returned object.
std::unique_ptr<IFoo> FooManager::getFoo()
{
switch(protocol)
{
case 1: return std::make_unique<Foo1>();
case 2:
default: return std::make_unique<Foo2>();
}
}
Since you have a very specific requirement I suggest a very specific solution for this exact problem (which may not be suitable elsewhere). In order to avoid having to use dynamic allocation and pointers or references you can "fake" polymorphism using function pointers. A small example given the requirements you mentioned in your comments:
class Foo {
public:
// function pointer aliases to make them easier to use
// I opted to make the two functions take different parameters for demonstration purposes
using isBar1Func = bool(*)(const Foo*);
using isBar2Func = bool(*)(int);
// constructor requiring the function pointers as parameters
Foo(int value, isBar1Func bar1func, isBar2Func bar2func) :
m_value(value), m_bar1Func(bar1func), m_bar2Func(bar2func) {}
bool isBar1() const {
return m_bar1Func(this);
}
bool isBar2() {
return m_bar2Func(m_value);
}
int getValue() const {
return m_value;
}
private:
int m_value;
isBar1Func m_bar1Func;
isBar2Func m_bar2Func;
};
// example functions to be passed into the constructor
static bool testBar1Func(const Foo* foo) {
return foo->getValue() != 0;
}
static bool testBar2Func(int value) {
return value > 1;
}
// getFoo can simply return a copy
Foo FooManager::getFoo() {
switch (protocol) {
case 1: return Foo(1, testBar1Func, testBar2Func);
// also works with non-capturing lambdas, which can be converted to function pointers
case 2: return Foo(2,
[](const Foo* foo) { return foo->getValue() != 1; },
[](int value) {return value != 12; });
// add remaining cases as desired
}
}
Thanks to #UnholySheep response, here is what I ended with:
class FooManager : public IFoo{
public:
using FooFunc = bool(*)(const IFoo&);
bool callFoo(FooFunc function) const{
switch(protocol) {
case 1: return function(Foo1());
case 2: return function(Foo2());
//and the other cases
}
}
bool isBar1() const override {
return callFoo([](const IFoo& foo){return foo.isBar1();});
}
bool isBar2() const override {
return callFoo([](const IFoo& foo){return foo.isBar2();});
}
};
my FooX classes stay the sames and the switch(protocol) is in a single function meaning that if a new protocol arrives, I just have to create a new FooY for that protocol and add it to the switch to get it working. All that with compile time checks and no use of the heap.
Thanks again #UnholySheep and the others as well.
I am writing googletest/googlemock-based unit tests for a class using a database object as a dependency, so I decided to mock the database. It provides read-only access to items of type Entry based on an index:
struct Entry {
int x, y;
};
class DbIface {
public:
virtual ~DbIface() {}
virtual int count() const = 0;
virtual const Entry& entry(const int idx) const = 0;
};
class DbMock : public DbIface {
public:
MOCK_CONST_METHOD0(count, int());
MOCK_CONST_METHOD1(entry, const Entry&(const int idx));
};
I want to specify some predefined data for the test and make the mock return that:
const std::vector<Entry> TEST_DATA = { { 0, 1 }, { 2, 3 }, { 4, 5 } };
DbMock mock;
EXPECT_CALL(mock, count).WillOnce(Return(TEST_DATA.size()));
EXPECT_CALL(mock, entry).WillOnce(Invoke([](int i) { return TEST_DATA.at(i); }));
However, I am getting an error on the last EXPECT_CALL:
warning C4172: returning address of local variable or temporary
I expect the GMock-generated wrapper makes a copy from the reference returned by the lambda somewhere along the way, but it's difficult to follow in that mess of code. In any case, how do I achieve what I need without changing the interface?
As clarified by this answer, the type of the TEST_DATA.at(i) expression is Entry, not const Entry&, so the lambda has its return type deduced to be non-reference, causing the problem.
This is fixed by explicitly stating the return type of the lambda:
EXPECT_CALL(mock, entry).WillOnce(Invoke([](int i) -> const Entry& { return TEST_DATA.at(i); }));
I am just starting my adventure in the land of C++, so this may be a silly question. I am getting the following error from my compiler.
Run.cc:56: error: no matching function for call to ‘sphereDetect::getArrayPtr() const’
/spheredetect.hh:18: note: candidates are: const G4long (* sphereDetect::getArrayPtr())[36][72][60]
my Run.hh is:
#include "spheredetect.hh"
#include "G4Run.hh"
#include "globals.hh"
class G4Event;
/// Run class
///
class Run : public G4Run
{
public:
Run();
virtual ~Run();
// method from the base class
virtual void Merge(const G4Run*);
void AddEdep (G4double edep);
// get methods
G4double GetEdep() const { return fEdep; }
G4double GetEdep2() const { return fEdep2; }
private:
G4double fEdep;
G4double fEdep2;
sphereDetect scatter;
};
my Run.cc is:
#include "Run.hh"
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Run::Run()
: G4Run(),
fEdep(0.),
fEdep2(0.),
scatter()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
Run::~Run()
{}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::Merge(const G4Run* run)
{
const Run* localRun = static_cast<const Run*>(run);
fEdep += localRun->fEdep;
fEdep2 += localRun->fEdep2;
arr* scatterPointer = localRun->scatter.getArrayPtr();
scatter.sphereMerge(scatterPointer);
G4Run::Merge(run);
}
//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
void Run::AddEdep (G4double edep)
{
fEdep += edep;
fEdep2 += edep*edep;
}
and my sphereDetect.hh is:
typedef G4long arr[36][72][60];
class sphereDetect
{
public:
sphereDetect();
~sphereDetect();
const arr* getArrayPtr() {return &scatterArray;}
void sphereMerge(arr*);
void createHit(G4ThreeVector,G4double);
protected:
void storeHit(G4int,G4int,G4int);
G4int findAngNS(G4ThreeVector);
G4int findAngEW(G4ThreeVector);
G4int findEnergy(G4double);
void sphereSave();
private:
G4long scatterArray[36][72][60];
};
I am fairly lost as to how to resolve this. Is it in the way i construct or call the sphereDetect class? The one thing that is certain is that the input for the Run.Merge is required to be that input(based on the previous code).
Any help is greatly appreciated,
Will
You're short a const.
const arr* getArrayPtr() {}
Means "this returns a const pointer".
const arr* getArrayPtr() const {}
Means "this returns a const pointer, and can be called on a const object". Otherwise, the compiler can't tell that getArrayPtr() doesn't want to modify the object on which it's called.
Since localRun is const, it's member localRun->scatter is const, too.
The compiler is looking for a definition of getArrayPtr() which declares that it will not modify the object and thus is safe to call on a const object. This is done by putting the const after the rest of the function signature, just like G4double GetEdep() const has it.