Im new to Gmock. I try a example but it's error. I also refer a few posts on the group but it not helpul for me.
class MATH
{
public:
virtual ~MATH(){}
virtual int Tong(int a, int b)
{
return a + b;
}
};
class MockMATH : public MATH
{
public:
MOCK_METHOD2(Tong, int(int,int));
};
class TestMATH
{
MATH m ;
public:
int TestTong(int a, int b)
{
cout<<"TONG"<<endl;
if(m.Tong(a,b))
{
cout<<"Successful"<<endl;
return a+b;
}
else
{
cout<<"Failed"<<endl;
return -1;
}
}
};
TEST(MyMathTest, Tong_by_true)
{
MockMATH mM;
TestMATH math;
EXPECT_CALL(mM,Tong(_,_));
//.WillOnce(Return(9));
int retValue = math.TestTong(4,5);
std::cout<<retValue<<std::endl;
EXPECT_EQ(retValue,9);
}
int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);
int ret = RUN_ALL_TESTS();
return ret;
}
and this error is showed below :
The problem is method Tong() is never called on your mock object mM. It is called on object m, member of TestMath class. That cannot work, m is not a mock object, gmock knows nothing about it and cannot track methods being called on it.
The simplest solution I see is:
class MATH { public: virtual ~MATH(){} virtual int Tong(int a, int b) { return a + b; } };
class MockMATH : public MATH
{
public:
MOCK_METHOD2(Tong, int(int,int));
};
class TestMATH
{
MockMATH m ;
public:
int TestTong(int a, int b)
{
std::cout<<"TONG"<<std::endl;
if(m.Tong(a,b))
{
std::cout<<"Successful"<<std::endl;
return a+b;
}
else
{
std::cout<<"Failed"<<std::endl;
return -1;
}
}
MockMATH& getMMath() { return m; }
};
TEST(MyMathTest, Tong_by_true)
{
TestMATH math;
EXPECT_CALL(math.getMMath(),Tong(_,_))
.WillOnce(Return(9));
int retValue = math.TestTong(4,5);
std::cout<<retValue<<std::endl;
EXPECT_EQ(retValue,9);
}
which passes the test.
Related
In C# we declare delegate function of a class like this:
public delegate void MyClassDelegate(float num);
And then we can use it on other functions like this:
public int SomeFunction(float num, MyClass.MyClassDelegate del);
How do I do this or something like this on QT?
It's not related to Qt. Use std::function for that:
void caller(int value, std::function<float(int)> delegate)
{
qDebug() << delegate(value);
}
float divide(int value)
{
return float(value) / 3;
}
int main(int argc, char *argv[])
{
caller(7, divide);
return 0;
}
If you need something elaborate (such as storing a state to create a proxy function, etc.), you can also use an object with a () operator:
struct MyDelegate
{
float operator()(int value) { return float(value) / 3; }
};
float divide(int value)
{
return float(value) / 3;
}
void caller(int value, MyDelegate& delegate)
{
qDebug() << delegate(value);
}
int main(int argc, char *argv[])
{
MyDelegate delegate;
caller(7, delegate);
return 0;
}
class Attraction {
};
class Museum : public Attraction {
private:
double price;
public:
void setPrice(double Price) {
price = Price;
}
double getPrice() {
return price;
}
};
class Park : public Attraction {
public:
double getPrice() {
return 0;
}
};
class Theatre : public Attraction {
private:
double price;
public:
void setPrice(double Price) {
price = Price;
}
double getPrice() {
return price;
}
};
int _tmain(int argc, _TCHAR* argv[]) {
vector<Attraction> attraction;
vector<Attraction>::iterator i;
for (i = attraction.begin(); i != attraction.end(); i++) {
if (i->getPrice() < 5) {
cout << endl;
}
}
}
vector<Attraction> performs object slicing, so you can never access getPrice() of derived classes. You need to use polymorphism instead, where you have a virtual double GetPrice() method in the Attraction class, and then use vector<Attraction*> with new/delete for the objects. Don't forget to make the destructor in Attraction virtual as well, so you can delete descendant object using a base pointer.
What you are attempting to do is not possible with the code you have shown. You are not utilizing polymorphism correctly.
Try something more like this instead:
class Attraction
{
public:
Attraction() {}
virtual ~Attraction() {}
virtual double getPrice(double Price)
{
return 0.0;
}
};
class PriceyAttraction : public Attraction
{
private:
double price;
public
PriceyAttraction(double Price = 0.0) : Attraction(), price(Price) {}
virtual double getPrice()
{
return price;
}
void setPrice(double Price)
{
price = Price;
}
};
class Museum : public PriceyAttraction
{
public:
Museum(double Price = 0.0) : PriceyAttraction(Price) {}
};
class Park : public Attraction
{
public:
Park() : Attraction() {}
};
class Theatre : public PriceyAttraction
{
public:
Theatre(double Price = 0.0) : PriceyAttraction(Price) {}
};
int _tmain(int argc, _TCHAR* argv[])
{
std::vector<Attraction*> attraction;
attraction.push_back(new Museum(5.00));
attraction.push_back(new Park);
attraction.push_back(new Theatre(7.50));
std::vector<Attraction*>::iterator i;
for (i = attraction.begin(); i != attraction.end(); ++i)
{
std::cout << i->getPrice() << std::endl;
//...
}
for (i = attraction.begin(); i != attraction.end(); ++i)
{
delete *i;
}
}
If you are using C++11 or later, you can use std::unique_ptr to manage the object deallocations for you:
int _tmain(int argc, _TCHAR* argv[])
{
std::vector<std::unique_ptr<Attraction>> attraction;
attraction.emplace_back(new Museum(5.00));
attraction.emplace_back(new Park);
attraction.emplace_back(new Theatre(7.50));
/* or:
attraction.push_back(std::unique_ptr<Attraction>(new Museum(5.00)));
attraction.push_back(std::unique_ptr<Attraction>(new Park));
attraction.push_back(std::unique_ptr<Attraction>(new Theatre(7.50)));
*/
/* or:
attraction.push_back(std::make_unique<Museum>(5.00));
attraction.push_back(std::make_unique<Park>());
attraction.push_back(std::make_unique<Theatre>(7.50));
*/
vector<Attraction>::iterator i;
for (i = attraction.begin(); i != attraction.end(); ++i)
{
std::cout << (*i)->getPrice() << std::endl;
//...
}
}
#include<string>
#include<iostream>
using namespace std;
template<class T>
class Student_Grades
{
string name;
int NoExams;
T *grades_ptr;
static int counter;
public:
Student_Grades(string n, int no)
{
name=n;
NoExams=no;
grades_ptr=new T[no];
counter++;
}
void Print()
{
cout<<"Name: "<<name<<endl;
cout<<"NoExams: "<<NoExams<<endl;
for(int i=0; i<NoExams; i++)
{
cout<<"Grade "<<i+1<<": "<<grades_ptr[i]<<endl;
}
cout<<endl<<endl;
}
void set_grade(int index, T grade)
{
grades_ptr[index]=grade;
}
T get_grade(int index)
{
return grades_ptr[index];
}
int get_counter()
{
return counter;
}
~Student_Grades()
{
delete[] grades_ptr;
counter--;
}
};
This code will create a different counter for every template specialization.
How do I make the counter global, meaning it will be incremented each time I create an object? In the Main, I created 3 Student_Grades objects, one with int specialization. one with double and one with char. The counter gives me 1. How do I get it to give me 3?
You can use a base class the aim of which is to count the number of instances:
#include<cassert>
struct B {
B() { cnt++; }
virtual ~B() { cnt--; }
static int cnt;
};
int B::cnt = 0;
template<typename T>
struct D: B {
D(): B{} { }
};
int main() {
D<int> d1;
D<float> d2;
assert(B::cnt == 2);
}
This way, it doesn't depend on the type of the specialization.
A slightly more configurable solution would be this one:
#include<cassert>
struct C {
C() { cnt++; }
virtual ~C() { cnt--; }
static int cnt;
};
int C::cnt = 0;
template<typename T, class Counter = C>
struct D: Counter { };
int main() {
D<int> d1;
D<float> d2;
assert(C::cnt == 2);
}
This one if you don't want to rely on inheritance:
#include<cassert>
struct C {
C() { cnt++; }
~C() { cnt--; }
static int cnt;
};
int C::cnt = 0;
template<typename T, class Counter = C>
struct D { const Counter c; };
int main() {
D<int> d1;
D<float> d2;
assert(C::cnt == 2);
}
And so on...
I have a problem with a c++ code I just written. The code is a sample of the Builder design pattern. I created an abstract builder class, and two classes inherited from this class: MonsterBuilder and RuffianBuilder. I created a Builder class, this class receives a Monster or a RuffianBuilder, and constructs a new instance of these classes. The problem comes here: if the MonsterBuilder class is used to build a new instance the program terminates with an error (a.exe has stopped working). If the Builder receives a RuffianBuilder, it constructs a new instance without an error. Here is the sample code:
#include <iostream>
class Character
{
private:
// Attributes
int dex;
int str;
int end;
// skills
int lockpick;
int guns;
int sneak;
/***************************************** Setters ********************************************************/
// Attribute setters
public:
void setStrength(const int &s)
{
this->str = s;
}
void setDexterity(const int &d)
{
this->dex = d;
}
void setEndurance(const int &e)
{
this->str = e;
}
// Skill setters
void setLockpick(const int &s)
{
this->lockpick = s;
}
void setSneak(const int &s)
{
this->sneak = s;
}
void setGuns(const int &s)
{
this->guns = s;
}
int getGuns()
{
return this->guns;
}
int getStrength()
{
return this->str;
}
};
/* Abstract builder */
class CharacterBuilder
{
protected:
Character * int_character;
public:
Character * getCharacter()
{
return int_character;
}
void buildCharacter()
{
int_character = new Character;
}
virtual void buildSkills() = 0;
virtual void buildAttributes() = 0;
};
class MonsterBuilder : public CharacterBuilder
{
public:
virtual void buildSkills()
{
int_character->setLockpick(10);
int_character->setSneak(12);
int_character->setGuns(50);
}
virtual void buildAttributes()
{
int_character->setStrength(5);
int_character->setDexterity(5);
int_character->setEndurance(5);
}
};
class RuffianBuilder : public CharacterBuilder
{
public:
virtual void buildSkills()
{
int_character->setLockpick(10);
int_character->setSneak(12);
int_character->setGuns(50);
}
virtual void buildAttributes()
{
int_character->setStrength(5);
int_character->setDexterity(5);
int_character->setEndurance(5);
}
};
class Builder
{
public:
void setBuilder(CharacterBuilder * builder)
{
this->builder = builder;
}
Character * getCharacter()
{
return builder->getCharacter();
}
void buildCharacter()
{
//std::cout << builder->buildSkills;
builder->buildSkills();
builder->buildAttributes();
}
private:
CharacterBuilder * builder;
};
int main()
{
Builder B;
RuffianBuilder R;
MonsterBuilder Mo;
B.setBuilder(&R);
B.buildCharacter();
std::cout << B.getCharacter()->getGuns();
std::cout << B.getCharacter()->getStrength();
B.setBuilder(&Mo);
B.buildCharacter();
//std::cout << B.getCharacter()->getStrength();
return 0;
}
What causes this problem? Could somebody explain it?
Reading uninitlalized variable will cause undefined behavior.
I added builder->buildCharacter(); to Builder::buildCharacter() and then this code seems working well.
class Builder
{
public:
void setBuilder(CharacterBuilder * builder)
{
this->builder = builder;
}
Character * getCharacter()
{
return builder->getCharacter();
}
void buildCharacter()
{
//std::cout << builder->buildSkills;
builder->buildCharacter(); // add this line
builder->buildSkills();
builder->buildAttributes();
}
private:
CharacterBuilder * builder;
};
I have a big project where I faced a problem, which can be shortly formulated as following:
I had a class which is created temporally and used to process and modify some data (let's call it "worker"). Now I have two workers and two corresponding data formats. The data array can contain mixed data, how to make my programm automatically decide which worker class it should create and use for data processing? How to make this in the best way?
To illustrate this problem I wrote small example programm, which is analogical to my project.
#include <iostream>
#include <vector>
using namespace std;
const int NInputs = 10;
struct TOutput {
int i;
};
class TProcess {
public:
TProcess( const vector<TInput>& i ){ fInput = i; }
void Run();
void GetOutput( TOutput& o ) { o = fOutput; }
private:
vector<TInput> fInput;
TOutput fOutput;
};
#if 0
struct TInput {
int i;
};
class TWorker{
public:
void Init( int i ) { fResult = i; }
void Add( int i ) { fResult += i; }
int Result() { return fResult; }
private:
int fResult;
};
#else
struct TInput {
int i;
};
class TWorker {
public:
void Init( int i ) { fResult = i; }
void Add( int i ) { fResult ^= i; }
int Result() { return fResult; }
private:
int fResult;
};
#endif
void TProcess::Run() {
TWorker worker;
worker.Init(0);
for( int i = 0; i < fInput.size(); ++i )
worker.Add(fInput[i].i);
fOutput.i = worker.Result();
}
int main() {
vector<TInput> input(NInputs);
for ( int i = 0; i < NInputs; i++ ) {
input[i].i = i;
}
TProcess proc(input);
proc.Run();
TOutput output;
proc.GetOutput(output);
cout << output.i << endl;
}
The example is very simple, but that doesn't means that it's simply possible to transform it to one function --- it corresponds to big project. Therefore it is not possible to:
delete classes or functions, which already exists (but possible to modify them and create new)
make workers static or create only one copy of worker (each workers are temporary in many complicated functions and loops)
So how to modify it such that this will be something like this:
// TODO: TProcess declaration
struct TInput1 {
int i;
};
class TWorker1{
public:
void Init( TInput1 i ) { fResult = i; }
void Add( TInput1 i ) { fResult += i.i; }
int Result() { return fResult; }
private:
int fResult;
};
#else
struct TInput2 {
int i;
};
class TWorker2 {
public:
void Init( TInput2 i ) { fResult = i.i; }
void Add( TInput2 i ) { fResult ^= i.i; }
int Result() { return fResult; }
private:
int fResult;
};
void TProcess::Run() {
for( int i = 0; i < fInput.size(); ++i ) {
// TODO: choose and create a worker
worker.Add(fInput[i].i);
// TODO: get and save result
}
fOutput.i = worker.Result();
}
int main() {
vector<TInputBase> input(NInputs);
// TODO: fill input
TProcess proc(input);
proc.Run();
TOutput output;
proc.GetOutput(output);
cout << output.i << endl;
}
My initial idea was to use basic class and template functions, but there is no template virtual functions...
You've got the right idea with the vector<TInputBase> declaration in your second example -- you need to have a common base class for all inputs, and similarly for all workers:
class TInput {
}
class TInput1 : public TInput { ... }
class TInput2 : public TInput { ... }
class TWorker {
public:
void Init(TInput *input) = 0;
void Add(TInput *input) = 0;
int Result() = 0;
}
class TWorker1 : public TWorker { ... }
class TWorker2 : public TWorker { ... }
Note, however, that this means all workers can only take a TInput * as input and you will need to cast to the correct input class inside each worker class.
The simplest way to decide which worker class to use for a given input is to ask the input itself! You can have a virtual function in the input class that creates the right kind of worker:
class TInput {
virtual TWorker *createWorker() = 0;
}
class TInput1 : public TInput {
TWorker *createWorker() {
return new TWorker1();
}
}
class TInput2 : public TInput {
TWorker *createWorker() {
return new TWorker2();
}
}
If this is not possible for some reason, you can use typeid to determine the type of the input and create a corresponding worker instance.