I am trying to mock global function using https://github.com/apriorit/gmock-global library.
Note: this description contains example of the real scenario not the exact real scenario. Also I am not allowed to make any changes to global.hpp.
My example dir structure looks like below
--src
------global.hpp
------classA.hpp
------classB.hpp
------main.cpp
--ut
------classATests.cpp
------classBTests.cpp
------main.cpp
The ut/main.cpp tests testcases in classATests.cpp and classBTests.cpp.
global.hpp contains a global function
int giveIndex()
{
return 1;
}
classA.hpp calls giveIndex() global function
#include "global.hpp"
class A
{
public:
int checkIndex() { return giveIndex(); };
}
classB.hpp calls giveIndex() global function
#include "global.hpp"
class B
{
public:
int checkIndex() { return giveIndex(); };
}
classATests.cpp contains
#include <memory>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <gmock-global/gmock-global.h>
#include "src/classA.hpp"
MOCK_GLOBAL_FUNC0(giveIndex, int(void));
using namespace ::testing
struct classATests : public ::testing::Test
{
void Setup() override
{
sut_ = std::make_shared<A>();
}
std::shared_ptr<A> sut_;
};
TEST_F(classATests , checkIndex)
{
EXPECT_GLOBAL_CALL(giveIndex, giveIndex()).WillOnce(Return(1));
sut_->checkIndex();
}
classBTests.cpp contains
#include <memory>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <gmock-global/gmock-global.h>
#include "src/classB.hpp"
MOCK_GLOBAL_FUNC0(giveIndex, int(void));
using namespace ::testing
struct classBTests : public ::testing::Test
{
void Setup() override
{
sut_ = std::make_shared<B>();
}
std::shared_ptr<B> sut_;
};
TEST_F(classBTests , checkIndex)
{
EXPECT_GLOBAL_CALL(giveIndex, giveIndex()).WillOnce(Return(1));
sut_->checkIndex();
}
The issue now is when i compile and run UT for both classATests.cpp and classBTests.cpp i get errors saying
... multiple definition of 'giveIndex' ;
and
... multiple definitions of gmock_globalmock_giveIndex_instance
Is there any way to avoid this issue ? classA tests and classB tests need to be in 2 different files like it is now.
Functions defined in header files should be defined inline
inline int giveIndex()
{
return 1;
}
otherwise you will get multiple definition errors if you include the header file more than once.
The alternative would be to only declare the function in your header file
int giveIndex();
and then define it (but not inline) in one of your cpp files.
This is the normal way to organise C++ code. gmock has nothing to do with this.
Related
I have a C++/WinRT base class that I need to subclass. My problem is that I don't manage to call the base class's protected constructor from the subclass.
That base class is defined in MIDL as follows:
namespace My.Custom.WindowsRuntimeComponent
{
unsealed runtimeclass BaseClass : Windows.UI.Xaml.Controls.SwapChainPanel
{
}
}
From it, the following header and implementation is created:
#pragma once
#include <DirectXMath.h>
#include "BaseClass.g.h"
namespace winrt::My::Custom::WindowsRuntimeComponent::implementation
{
struct BaseClass : BaseClassT<BaseClass>
{
protected:
BaseClass();
::DirectX::XMFLOAT3 ProtectedMethod();
};
}
#include "pch.h"
#include "BaseClass.h"
#include "BaseClass.g.cpp"
namespace winrt::My::Custom::WindowsRuntimeComponent::implementation
{
BaseClass::BaseClass()
{
// Important stuff happening here
}
::DirectX::XMFLOAT3 BaseClass::ProtectedMethod()
{
return ::DirectX::XMFLOAT3();
}
}
The subclass's MIDL, header and implementation are defined as follows:
import "BaseClass.idl";
namespace My.Custom.WindowsRuntimeComponent
{
runtimeclass SubClass : BaseClass
{
SubClass();
void UseProtectedMethod();
}
}
#pragma once
#include "BaseClass.h"
#include "SubClass.g.h"
namespace winrt::My::Custom::WindowsRuntimeComponent::implementation
{
struct SubClass : SubClassT<SubClass, My::Custom::WindowsRuntimeComponent::implementation::BaseClass>
{
SubClass();
void UseProtectedMethod();
};
}
namespace winrt::My::Custom::WindowsRuntimeComponent::factory_implementation
{
struct SubClass : SubClassT<SubClass, implementation::SubClass>
{
};
}
#include "pch.h"
#include "SubClass.h"
#include "SubClass.g.cpp"
namespace winrt::My::Custom::WindowsRuntimeComponent::implementation
{
SubClass::SubClass()
{
}
void SubClass::UseProtectedMethod()
{
::DirectX::XMFLOAT3 value = ProtectedMethod();
}
}
The above example compiles. However, if I attempt to call the protected base class constructor from the initializer list of the subclass as shown below I receive a compiler error.
#include "pch.h"
#include "SubClass.h"
#include "SubClass.g.cpp"
namespace winrt::My::Custom::WindowsRuntimeComponent::implementation
{
SubClass::SubClass() : BaseClass() // This line does not compile
{
}
void SubClass::UseProtectedMethod()
{
::DirectX::XMFLOAT3 value = ProtectedMethod();
}
}
The compiler error is as follows:
error C2614: 'winrt::My::Custom::WindowsRuntimeComponent::implementation::SubClass': illegal member initialization: 'BaseClass' is not a base or member
Both in the MIDL and the header of SubClass I specify that it inherits from BaseClass so it is unclear to me why the compiler emits that error.
I could work around that problem, I guess, but I'm curious about what exactly is going on here. Any hints?
The SubClass in the winrt::... namespace derives from SubClassT<...>, not from SubClass.
The SubClass that is outside the winrt:: namespace derives from BaseClass, but thats a different one. Your naming is easy to get lost in.
I'm new to google mock and I'm trying to mock an interface, but keep getting a linker error with undefined symbols for architecture x86_64
Here's my simplified code:
I have the following in a .h file:
namespace Mynamespace
{
class IMyInterface
{
public:
virtual ~ IMyInterface() {};
virtual void myFunction() = 0;
};
}
this in another .h file:
#include <gmock/gmock.h>
#include <IMyInterface.h>
namespace testing
{
class MyClassMock : public IMyInterface
{
public:
~ MyClassMock();
MyClassMock(int, int, int);
MOCK_METHOD0(myFunction, void());
};
}
and this in my Test Case .cpp file:
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <IMyInterface.h>
namespace testing
{
TEST(MyClassMock, myFunction)
{
MyClassMock mcm(0,0,0);
}
}
Do you have an idea what am I doing wrong?
Any help would be very much appreciated!
cheers,
Simon
EDIT:
Unfortunately the mock still doesn't seem to work. After I added the implementation like this:
namespace testing
{
MyClassMock:: MyClassMock(int a, int b, int c)
{
}
MyClassMock::~ MyClassMock()
{
}
}
"myFunction" will not be called when I do
#include "MyClassMock.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
using ::testing::AtLeast;
using namespace testing;
TEST(MyClassTest, canCallFunction)
{
MyClassMock mock(0,0,0);
EXPECT_CALL(mock, myFunction())
.Times(AtLeast(1));
}
returning:
EXPECT_CALL(mock, myFunction())
Expected: to be called at least once
Actual: never called - unsatisfied and active
You have to provide implementations for MyClassMock::MyClassMock(int, int, int) and MyClassMock::~MyClassMock().
On a side not, you should use "" rather than <> when you #include your own headers. E.g. #include "IMyInterface.h" not #include <IMyInterface.h>. That way, the compiler will search in the current directory prior to the system include path.
I have a PieceStrategy class:
#include "QueenStrategy.cpp"
class PieceStrategy {
void promoteToQueen() {
this = new QueenStrategy();
}
}
And I have a QueenStrategy class which inherits from it:
#include "PieceStrategy.cpp"
class QueenStrategy : public PieceStrategy {}
Now arises the circular includes problem. But in this case, I cannot use forward declaration.
What should I do?
You should not include cpp files, but headers
You must not assign to this
Choose another design. You should not try to modify the strategy but select another one for the actual object, that uses that strategy.
piece.hpp
#include "strategy.hpp"
class Piece
{
std::unique_ptr<Strategy> strategy;
public:
static Piece Pawn();
void PromoteToQueen();
};
piece.cpp
#include "pawn.hpp"
#include "queen.hpp"
Piece Piece::Pawn()
{
Piece p;
p.strategy = std::make_unique<PawnStrategy>();
return p;
}
void Piece::PromoteToQueen()
{
strategy = std::make_unique<QueenStrategy>();
}
I have a similar problem to this but not the exact.
Assuming we have 2 header files and a main.cpp.
In the first header file we have :
namespace Logic
{
class GameManager;
}
In the second header:
#include "first_header.h"
class Logic::GameManager
{
public :
void init();
void run():
};
And in the main.cpp i have :
#include "first_header.h"
int main()
{
Logic::GameManager gm;
gm.init();
gm.run();
}
I get this error until i include the second header in main.cpp :
'gm' uses undefined class 'Logic::GameManager'
-Is this way of using namespaces and classes correct ?
-Is there a better way to do this?
Thanks.
Re-open the namespace to define the class.
namespace Logic {
class GameManager
{
public :
void init();
void run():
};
}
And include the second header, not the first, from main.cpp. The compiler cannot find the class definition unless it is directly #include'd.
I hope that I am providing enough information and that I've titled this correctly.
In general, I want to have a class that stores data in my application, and I need several other classes to access the same data. essentially sharing the data between multiple classes.
Short/Concise Code follows:
example.cpp (main application)
// example.cpp : Defines the entry point for the console application.
//
#include "AnotherClass.h"
#include "ObjectClass.h"
#include "stdafx.h"
#include <iostream>
#include <iomanip>
using namespace std;
//Prototype
static void do_example ( );
int main()
{
do_example ( );
}
static void do_example ( ) {
MyObject.a = 5;
cout <<"MyObject.a value set in main application is "<<MyObject.a<<"\n";
AnotherClass m_AnotherClass;
m_AnotherClass.PrintValue();
}
ObjectClass.h
class ObjectClass {
public:
ObjectClass(); // Constructor
int a; // Public variable
} static MyObject;
ObjecClass.cpp
#include "ObjectClass.h"
ObjectClass::ObjectClass() {
a = 0;
}
AnotherClass.h
class AnotherClass {
public:
AnotherClass(); // Constructor
void PrintValue(); // Public function
int value; // Public variable
};
AnotherClass.cpp
#include "AnotherClass.h"
#include "ObjectClass.h"
#include "stdafx.h"
#include <iostream>
#include <iomanip>
using namespace std;
AnotherClass::AnotherClass() {
value = MyObject.a;
}
void AnotherClass::PrintValue() {
cout <<"value in AnotherClass is "<<value<<"\n";
cout <<"it should be the same."<<"\n";
}
But the value is the default value of 0, as if it is a new instance of MyObject. But it should be pulling the value of 5 from the static MyObject.
What am I missing?
A static class instance is a static variable itself. What you expect to happen also makes sense, however, your code does not show how the static instance is handled. In fact, if both MyClassInstances refer to the same object, then you don't even need static declaration.
Also, static variables are defined in cpp files. If you define it in a header, the cpp file (compilation unit) that includes it will define a separate static variable. So, define the static object in the main cpp file and use extern MyStaticClass in the header file. The linker will then link the uses to the same variable.