I am trying to learn gtest. I have my class Calculator that I want to test.
#pragma once
// whattotest.cpp
#include <math.h>
class Calculator{
public:
double squareRoot(const double a) {
double b = sqrt(a);
if(b != b) { // nan check
return -1.0;
}else{
return sqrt(a);
}
}
double add (const double a, const double b){
return (a + b);
}
double multiply(const double a, const double b){
return (a * b);
}
};
I have the test class code below.
#include "gtest_example.hpp"
#include <gtest/gtest.h>
using namespace std;
class CalculatorTest : public ::testing::Test {
protected:
virtual void SetUp() {
calc = new Calculator();
}
virtual void TearDown() {
delete calc;
}
Calculator *calc;
};
TEST(CalculatorTest, ShouldReturnSum) {
SetUp();
ASSERT_EQ(72, calc->add(36.0, 36.0));
}
TEST(CalculatorTest, ShouldReturnProduct) {
SetUp();
ASSERT_EQ(36, calc.multiply(6.0, 6.0));
}
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
In both the ASSERT_EQ lines I get the following errors.
Even after macro substitution can't resolve the variable calc.
What am I doing wrong hee.
As you use fixture, you should use macro TEST_F instead of TEST.
class CalculatorTest : public ::testing::Test {
Calculator calc;
};
TEST_F(CalculatorTest, ShouldReturnSum)
{
ASSERT_EQ(72, calc.add(36.0, 36.0));
}
TEST_F(CalculatorTest, ShouldReturnProduct)
{
ASSERT_EQ(36, calc.multiply(6.0, 6.0));
}
Without fixture, you might simply do:
TEST(CalculatorTest, ShouldReturnSum)
{
Calculator calc;
ASSERT_EQ(72, calc.add(36.0, 36.0));
}
TEST(CalculatorTest, ShouldReturnProduct)
{
Calculator calc;
ASSERT_EQ(36, calc.multiply(6.0, 6.0));
}
Related
I started to learn some oop and I have a question, why I can't put the function in first class, I know there is a way to write the friend method down under second class. If I put it in the first class where it belongs my compiler shows the error C2027: "Error C2027 use of undefined type 'Calculator'"
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <ctime>
using namespace std;
class Calculator;
class PlacadeBaza {
char denumire_procesor[100];
public:
char* getDenumire() {
return denumire_procesor;
}
void set(Calculator a, PlacadeBaza b, int memorie, char denumire[100]) { //C2027
a.memorie_RAM = memorie;
strcpy(b.denumire_procesor, denumire); //C2027
}
};
class Calculator {
int memorie_RAM;
public:
int getMemorie_RAM() {
return memorie_RAM;
}
friend void PlacadeBaza::set(Calculator a, PlacadeBaza b, int memorie, char denumire[100]);
};
int main() {
Calculator a;
PlacadeBaza b;
int memorie;
char denumire[100];
cin >> memorie >> denumire;
b.set(a, b, memorie, denumire);
cout << a.getMemorie_RAM();
cout << b.getDenumire();
}
Setting aside other issues with the code, if you wish PlacadeBaza to be able to access private members of Calculator you need to declare that PlacadeBaza is a friend class of Calculator.
#include <iostream>
#include <ctime>
using namespace std;
class PlacadeBaza;
class Calculator {
int memorie_RAM;
public:
int getMemorie_RAM() {
return memorie_RAM;
}
friend class PlacadeBaza;
};
class PlacadeBaza {
char denumire_procesor[100];
public:
char* getDenumire() {
return denumire_procesor;
}
void set(Calculator a, PlacadeBaza b, int memorie, char denumire[100]) { //C2027
a.memorie_RAM = memorie;
strcpy(b.denumire_procesor, denumire); //C2027
}
};
int main() {
Calculator a;
PlacadeBaza b;
int memorie;
char denumire[100];
cin >> memorie >> denumire;
b.set(a, b, memorie, denumire);
cout << a.getMemorie_RAM();
cout << b.getDenumire();
}
I am using c++11 compiler.
I have two classes - class Test and class TestHelper.
The class Test is a friend-to-class TestHelper.
The class Test is only which we can access from outside.
Now, we want to call Test API i.e. setVal(). This setVal() should call
Test2 API i.e. setX and is expecting this pointer. I don't want to use this pointer but want
to use a smart pointer instead. How can I do so?
The notion of this kind of desirability is because of the fact that in reality, my class Test is pretty big. So, I am trying to make a helper class for Test i.e.
class TestHelper;
class Test
{
friend class TestHelper;
int x;
public:
void display() {
std::cout << x;
}
void setVal(int val) {
TestHelper testH;
testH.setX(this, 324);
}
};
class TestHelper
{
public:
void setX(Test *test, int val) {
/** some algorithm here and then change val to something else */
test->x = val*100;
}
};
int main()
{
std::cout << "Hello World!\n";
Test x;
x.setVal(130);
}
I tried changing the prototype from void setX(Test *test, int val)
to void setX(std::shared_ptr<Test> test, int val) but don't know how to pass this pointer
as std::shared_ptr<Test> test here.
So here is working solution with shared pointers. The example doesn't even compile due to missing definitions so you have to restructure your code into headers and cpp files.
Test.h:
#ifndef TEST_H
#define TEST_H
#include <memory>
#include "TestHelper.h"
class Test : public std::enable_shared_from_this<Test>
{
private:
friend class TestHelper;
int x;
public:
void display();
void setVal(int val);
};
#endif
Test.cpp:
#include <iostream>
#include "Test.h"
void Test::display() {
std::cout << x;
}
void Test::setVal(int val) {
TestHelper testH;
testH.setX(shared_from_this(), 324);
}
TestHelper.h:
#ifndef TESTHELPER_H
#define TESTHELPER_H
class Test;
class TestHelper
{
public:
void setX(std::shared_ptr<Test> test, int val);
};
#endif
TestHelper.cpp:
#include <memory>
#include "TestHelper.h"
#include "Test.h"
void TestHelper::setX(std::shared_ptr<Test> test, int val) {
/** some algorithm here and then change val to something else */
test->x = val*100;
}
main.cpp:
#include <iostream>
#include <memory>
#include "Test.h"
int main(void){
std::cout << "Hello World!\n";
auto x = std::make_shared<Test>();
x->setVal(130);
x->display();
}
You can run it here: https://paiza.io/projects/e/79dehCx0RRAG4so-sVZcQw
I don't understand why you want this, here's a few variants that compile
reference
// Reference variant
#include <iostream>
class Test;
class TestHelper
{
public:
void setX(Test & test, int val);
};
class Test
{
friend class TestHelper;
int x;
public:
void display() {
std::cout << x;
}
void setVal(int val) {
TestHelper testH;
testH.setX(*this, 324);
}
};
void TestHelper::setX(Test &test, int val)
{
/** some algorithm here and then change val to something else */
test.x = val*100;
}
int main()
{
Test x;
x.setVal(130);
x.display();
}
http://cpp.sh/7t3ec
shared ptr
// Shared ptr variant
#include <iostream>
#include <memory> // Required for shared_ptrs
class Test;
class TestHelper
{
public:
void setX(std::shared_ptr<Test> test, int val);
};
class Test : public std::enable_shared_from_this<Test>
{
friend class TestHelper;
int x;
public:
void display() {
std::cout << x;
}
void setVal(int val) {
TestHelper testH;
testH.setX(shared_from_this(), 324);
}
};
void TestHelper::setX(std::shared_ptr<Test> test, int val)
{
/** some algorithm here and then change val to something else */
test->x = val*100;
}
int main()
{
auto x = std::make_shared<Test>(); // x needs to be created as shared_ptr or it won't work
x->setVal(130);
x->display();
}
http://cpp.sh/87ao2
Perhaps with these you can refine your question?
Object-oriented C++ here.
I'm supposed to code a Microwave object that "heats" a FrozenMeal object.
One method of the Microwave object, called void heatMeal(FrozenMeal), is supposed to take an instance of a FrozenMeal object as a parameter and increase its temperature.
FrozenMeal.h
#include <string>
class FrozenMeal {
public:
FrozenMeal(std::string, int);
void setTemperature(double);
std::string getName() const;
int getVolume() const;
double getCoeffizient() const;
double getTemperature() const;
private:
std::string name;
int volume;
double temperature;
double coeffizient;
};
FrozenMeal.cpp
#include <string>
#include "FrozenMeal.h"
using namespace std;
FrozenMeal::FrozenMeal(string mealName, int mealVolu) {
name = mealName;
volume = mealVolu;
temperature = -18;
coeffizient = 0.24;
}
void FrozenMeal::setTemperature(double mealTemp) { temperature = mealTemp; }
string FrozenMeal::getName() const { return name; }
int FrozenMeal::getVolume() const { return volume; }
double FrozenMeal::getCoeffizient() const { return coeffizient; }
double FrozenMeal::getTemperature() const { return temperature; }
Microwave.h
#include "FrozenMeal.h"
class Microwave {
public:
Microwave();
void morePower();
void lessPower();
void setPeriod(double);
void heatMeal(FrozenMeal); // <----------------------------
int getPower() const;
double getPeriod() const;
private:
int power;
double period;
};
Microwave.cpp
#include "Microwave.h"
using namespace std;
Microwave::Microwave() {}
void Microwave::morePower() { if (power < 1000) power += 200; }
void Microwave::lessPower() { if (power > 200) power -= 200; }
void Microwave::setPeriod(double sessionPeri) { period = sessionPeri; }
void Microwave::heatMeal(FrozenMeal mealInst) {
mealInst.setTemperature(80); //example
}
int Microwave::getPower() const { return power; }
double Microwave::getPeriod() const { return period; }
Now, my problem is that my compiler says that the file FrozenMeal.h apparently redefines the object type of FrozenMeal, even though that should be the job of the FrozenMeal.cpp file, and compiling is unsuccessful.
I tried including FrozenMeal.h to Microwave.cpp but that resulted in even more compiler errors.
I feel like I'm doing something horribly wrong here.
Add include guards to your header files so its contents doesn't get included more than once:
FrozenMeal.h:
#ifndef FROZENMEAL_H_INCLUDED
#define FROZENMEAL_H_INCLUDED
// your code ...
#endif /* FROZENMEAL_H_INCLUDED */
Microwave.h:
#ifndef MICROWAVE_H_INCLUDED
#define MICROWAVE_H_INCLUDED
// your code ...
#endif /* MICROWAVE_H_INCLUDED */
Also, you never initialize int Microwave::power and double Microwave::period so you will read and write garbage values in Microwave::morePower() and Microwave::lessPower()
As suggested in the comments, you want to take the parameter of Microwave::heatMeal() by reference so the function can modify the passed object:
void Microwave::heatMeal(FrozenMeal &mealInst)
// ^
I have a class with 3 fields a,b and c. I want to calculate the volume of a box with sides a,b or c. I want to do this with a friend function. However, when I compile the program the Compiler gives an error No global operator found which takes type Box. I would like to ask why is that?
#include "pch.h"
#include <iostream>
using namespace std;
class Box {
double a, b, c;
public:
Box(double sa, double sb, double sc) {
a = sa;
b = sb;
c = sc;
}
friend double calcVolume(Box bx) {
return bx.a*bx.b*bx.c;
};
};
int main() {
Box a(5.67, 6.43, 7.00),b(90,32.76,44.18);
cout << calcVolume(a)<<endl;
return 0;
}
There is a mistake in you code return bx.a*bx.b*bx*c;, which should be return bx.a*bx.b*bx.c; (the last dot)
#include <iostream>
using namespace std;
class Box {
double a, b, c;
public:
Box(double sa, double sb, double sc) {
a = sa;
b = sb;
c = sc;
}
friend double calcVolume(Box &bx) {
return bx.a * bx.b * bx.c;
};
};
int main() {
Box a(5.67, 6.43, 7.00),b(90,32.76,44.18);
cout << calcVolume(a)<<endl;
return 0;
}
A couple of things : use const when you are not modifying the argument, second do not do using namespace std. Now, this works for me
#include <iostream>
class Box
{
double a;
double b;
double c;
public:
Box(double ain, double bin, double cin) {a = ain; b = bin; c = cin;}
friend double calcVol(const Box& rOther)
{
return rOther.a*rOther.b*rOther.c;
}
};
int main()
{
Box a(14.8, 10.8, 11.01), b(8,5.0,6.2);
std::cout<<"vol a :: "<<calcVol(a)<<std::endl;
std::cout<<"vol b :: "<<calcVol(b)<<std::endl;
return 0;
}
I have a simple example class. It has one data member, which is a std::vector of pointers to armadillo matrices. the constructor takes such a vector as the only argument. here's file TClass.cpp:
#include <armadillo>
#include <vector>
class TClass {
private:
std::vector<arma::mat * > mats;
public:
TClass(std::vector<arma::mat * > m_);
arma::mat * GetM( int which ){ return( mats.at(which) );};
};
TClass::TClass(std::vector<arma::mat * > m_){
mats = m_;
}
I want to construct a GTest fixture to test member function GetM. Here is what I have done:
#include <gtest/gtest.h>
#include "TClass.cpp"
class TClassTest : public ::testing::Test {
protected:
int n;
int m;
std::vector<arma::mat * > M;
virtual void SetUp() {
n = 3;
m = 2;
arma::mat M1 = arma::randu<arma::mat>(n,m);
arma::mat M2 = arma::randu<arma::mat>(n,m);
M.push_back( &M1);
M.push_back( &M2);
}
// virtual void TearDown() {}
// initiate a TClass object
TClass T(M);
};
// my test
TEST_F(TClassTest, CanGetM1){
EXPECT_EQ( T.GetM(0), M.at(0) );
}
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
I compile this with g++ TClassTest.cpp -o tclass -larmadillo. It tells me that TClassTest.cpp:24: error: ‘M’ is not a type. I dont' understand why I cannot construct the TClass object in the fixture definition?
The object T cannot be initialized in the declaration of class TClassTest. Have you been writing Java lately? ;-)
To initialize it, you can do something like this:
class TClassTest : public ::testing::Test {
// ... (rest of code is fine as is)
virtual void SetUp() {
// ...
T = new TClass(M);
}
virtual void TearDown() { delete T; }
TClass *T;
};