I am learning GMock in gtest. I have a below scenario
class Observer
{
public:
virtual void StartObserver(const std::string&, const int&) { }
};
class MockObserver : public Observer
{
public:
MOCK_METHOD2(StartObserver, void(const std::string &, const int &));
};
class Worker
{
private :
std::shared_ptr<observer> mObserver = nullptr;
public :
void StartObserver(const std::string& str, const int& val)
{
mObserver->StartObserver(str, val);
}
void RegisterObserver(std::shared_ptr<Observer> observer)
{
mObserver = observer;
}
};
In my Test function I did the testing like below
TEST_(AppTest, Test_Observer)
{
Worker w;
std::shared_ptr<MockObserver> mockObserver = std::make_shared<MockObserver>();
w.RegisterObserver(mockObserver); //instead of actual ObserverObject I passed mockObserver here
EXPECT_CALL (*mockObserver, StartObserver(_, _)).Times(1).WillOnce(::testing::Return());;
w.StartObserver("hello", 100);
}
While running gTest I am getting below error on this test
Actual function call count doesn't match EXPECT_CALL(*mockObserver, StartObserver(_, _))...
Expected: to be called once
Actual: never called - unsatisfied and active
Is there anything wrong with my code ?
Related
Here is a simplified example (from gMock Cookbook) of a class template that I want to mock:
class StackInterface {
public:
virtual ~StackInterface();
virtual int GetSize() const {
return 3;
}
};
template<typename Elem>
class MockStack : public StackInterface<Elem> {
public:
MockStack() : StackInterface<Elem>(){};
MOCK_METHOD(int, GetSize, (), (const, override));
};
I'm using it as follows:
class StackTest : public testing::Test {
public:
StackTest() {
mockStack_ = std::make_shared<MockStack<int>>();
}
protected:
std::shared_ptr<MockStack<int>> mockStack_;
};
TEST_F(StackTest, TestGetSize1) {
EXPECT_CALL(*mockStack_, GetSize()).WillRepeatedly(testing::Invoke([&]() -> int { return 5; }));
StackInterface<int> myStack;
auto res = myStack.GetSize();
EXPECT_EQ(res, 5);
}
This test fails because returned value is 3 which is my real function - Why is my mock implementation being ignored? How can I ensure the mock implementation is used?
The GetSize method needs to be called by the mock object. That's mockStack_
template <typename Elem>
class StackInterface {
public:
StackInterface() {}
virtual ~StackInterface() {}
virtual int GetSize() const {
return 3;
}
};
template <typename Elem>
class MockStack : public StackInterface<Elem> {
public:
MockStack() : StackInterface<Elem>() {
ON_CALL(*this, GetSize()).WillByDefault(Return(1)); }
~MockStack() {}
MOCK_METHOD(int, GetSize, (), (const, override));
};
class StackTest : public testing::Test {
public:
StackTest() {
mockStack_ = std::make_shared<MockStack<int>>();
}
protected:
std::shared_ptr<MockStack<int>> mockStack_;
};
TEST_F(StackTest, TestGetSize1) {
EXPECT_CALL(*mockStack_, GetSize()).WillRepeatedly(testing::Invoke([&]() -> int { return 5; }));
EXPECT_EQ(mockStack_->GetSize(), 5);
}
I am writing an Arduino program where LEDs and a bunch of other electronics are controlled by different buttons. To simplify the code, I am using the Observer Mode:
class Observer observes EventThrowers, who performs check() every frame and notifies Observers if necessary. The code definition for Observer and EventThrower looks like this:
class Observer {
public:
virtual void handleEvent(int label, bool state) = 0; // Virtual method called by EventThrowers.
};
class EventThrower {
private:
std::vector<Observer *> observer_list;
protected:
void notifyObservers(int label, bool state) {
for (Observer *observer : observer_list) {
observer->handleEvent(label, state);
}
}
public:
virtual void check() = 0; // Virtual method used in loop() for frame checking.
void addObserver(Observer *_observer) {
this->observer_list.push_back(_observer);
}
};
And my LEDCtrl class (an Observer) and ButtonClick class (an EventThrower) definitions are:
class LEDCtrl : public Observer {
public:
// properties
LEDCtrl(int _led_pin) { ... } // constructor
void handleEvent(int label, bool state) { ... } // overridden handleEvent method
private:
void toggleLight(bool new_status) { ... } // assistant method
};
class ButtonClick : public EventThrower {
public:
// properties
ButtonClick(int _button_pin, int _default, int _label) { ... } // constructor
void check() { ... } // overridden check() that is called every frame to check the status of the button and choose to notify Observers or not
};
My initialization of a LEDCtrl-ButtonClick instance pair looks like:
ButtonClick *buttonClick1 = new ButtonClick(BUTTON1, 0, 0);
LEDCtrl *ledCtrl1 = new LEDCtrl(LED1);
buttonClick1->addObserver(ledCtrl1);
However, the above code throws this compile error:
error: 'buttonClick1' does not name a type
buttonClick1->addObserver(ledCtrl1);
^~~~~~~~~~~~
How can I fix this?
I did a small exemple to try to explain you with my poor english what I want to do :).
I have a main class who is my engine. This is my parent class of several children.
this is the parent class :
#include <string>
#include <iostream>
#include <vector>
template <typename Type>
class A
{
public:
A(std::string const &str)
: m_str(str)
{
}
void run(void) const {
unsigned int i;
for(i = 0; ACTIONS[i].f != nullptr; i++) {
if(m_str == ACTIONS[i].key) {
return ((*(this).*ACTIONS[i].f)(m_str));
}
}
}
protected:
typedef struct s_action {
std::string key;
void (Type::*f)(std::string const &);
} t_action;
static t_action const ACTIONS[];
std::string m_str;
};
class B : public A<B>
{
public:
B(std::string const &str);
protected:
static t_action const ACTIONS[];
void error(std::string const &str);
void success(std::string const &str);
};
I would like to call children method with table pointer of member function in this parent class A::run as you can see above
This code does not compile.
I know it's not possible to have a static variable virtual, but it's
exactly that I need to do have for A::ACTIONS. I absolutely need to initialise B::ACTIONS to A::run works.
In first Is it possible? Have you got a small exemple of this case?
This is the end of my small code :
#include "Class.hpp"
B::t_action const B::ACTIONS[] = {
{"ERROR", &B::error},
{"SUCCESS", &B::success},
{"", nullptr}
};
B::B(std::string const &str)
: A<B>(str)
{
}
void B::error(std::string const &str) {
std::cerr << str << std::endl;
}
void B::success(std::string const &str) {
std::cout << str <<std::endl;
}
And the main:
#include "Class.hpp"
int main() {
B b("SUCCESS");
b.run();
return (0);
}
I didn't try, normally this code should Display SUCCESS on stdout
Thank you for your help
void run(void) const
{
unsigned int i;
for(i = 0; ACTIONS[i].f != nullptr; i++)
if (m_str == ACTIONS[i].key)
return ((*(this).*ACTIONS[i].f)(m_str));
}
There are multiple reasons why this fails to compile. Not one, but several reasons. This entire dispatching mechanism must be completely redesigned.
The first order of business is that this is a
void run(void) const
A const class method.
The method pointer in question is:
void (Type::*f)(std::string const &);
The method pointer is not const, but mutable. From an existing const class method, you can only invoke other const methods. You cannot invoke non-const methods, either directly or indirectly via a method pointer, from a const class methods.
So the first order of business is to change this to
void (Type::*f)(std::string const &) const;
This also means that all your methods, in the child class, error() and success(), must also be const class methods too.
If it's necessary to use this dispatch mechanism with non-const methods, the run() method cannot be a const class method itself. But this is not the only problem here, so I'll continue with the const method, at hand.
return ((*(this).*ACTIONS[i].f)(m_str));
The this here, is a A<Type>. This is a method of that class. That's what this is here.
The method pointer, f is pointer to a method of Type, not A<Type>. Type is a subclass of A<Type>, and you cannot convert a pointer or a reference to a base class to a pointer or a reference to a subclass, any more than you can take a pointer to A, and convert to a pointer to B when B inherits from A. C++ does not work this way.
The solution is simple, and requires only a few small tweaks. This run() should take a reference to const Type &, and invoke the method via the passed-in reference, then a replacement abstract run() method invokes it, passing *this as a parameter:
public:
virtual void run()=0;
protected:
void run_me(const Type &me) const
{
unsigned int i;
for(i = 0; ACTIONS[i].f != nullptr; i++)
if (m_str == ACTIONS[i].key)
return ((me.*ACTIONS[i].f)(m_str));
}
Then, each subclass that inherits this template only needs to implement a simple facade:
class B : public A<B>
{
public:
void run() const override
{
run_me(*this);
}
EDIT: This addresses the compilation error, but additional work is needed to deal with the fact that static class members cannot be overridden. The solution is also pretty simple: also leverage virtual class methods in order to implement this.
Remove the declaration of ACTIONS from the template base class, and replace it with an abstract function:
virtual const t_action *get_actions() const=0;
And use it in run_me():
const t_action *ACTIONS=this->get_actions();
The rest of run_me() remains as is, and then implement get_actions() in the child class:
const t_action *get_actions() const override
{
return ACTIONS;
}
Pretty much everything else remains the same.
The problem is that A will always use is own defined set of actions, not B's.
You don't need to create A at all, as you want to use B methods and list of methods.
Let's say that you create first a run call function:
template<typename T>
void run(T* obj, const std::string method)
{
const auto& available_methods = obj->get_methods();
auto iter = available_methods.find(method);
if(iter == available_methods.end())
{
// Handle this case
}
std::invoke(iter->second, obj); //C++17, or (obj->*(iter->second))();
}
Now for the class B, you need something very simple:
class B
{
public:
typedef std::unordered_map<std::string, void(B::*)()> MethodMap;
void foo();
static MethodMap& get_methods()
{
static MethodMap map{{"foo", &B::foo}};
return map;
}
};
Populate the map with get_methods() in the static function, and then call run through:
int main()
{
B b;
run(&b, "foo");
}
If you are going to use CRTP, IMO you need to google for CRTP first.
By the way here's a quick direct ans 2 your q:
template<typename crtp_child>
class crtp_base{
using crtp_target=crtp_child;
auto crtp_this(){
return static_cast<crtp_target*>(this);
};
auto crtp_this() const {
return static_cast<crtp_target const*>(this);
};
public:
void run(){
auto range=crtp_this()->actions.equal_range(m_str);
for(auto entry:range)
(crtp_this()->*(entry.second))(m_str);
};
protected:
crtp_base(std::string str):
m_str(str)
{};
std::string m_str;
//...
};
struct crtp_user:
crtp_base<crtp_user>
{
using crtp_base::crtp_base;//ctor fwding
protected:
friend class crtp_base<crtp_user>;
std::unordered_multimap<std::string, void (crtp_user::*)(std::string)> actions;
//...
};
I have mock defined as follows:
template<typename T>
class ParseTreeMock : public ParseTreeInterface<T> {
public:
MOCK_METHOD1(fillConfigTree, void(std::string const&));
MOCK_METHOD1_T(getProperty, T(std::string const&));
ParseTreeMock(): parseTree(std::make_unique<pt::ptree>()) {
}
static std::unique_ptr<ParseTreeInterface<T>> getDefaultTree() {
return std::make_unique<ParseTreeMock<T>>();
}
private:
std::unique_ptr<pt::ptree> parseTree;
};
which is created later in test case:
class ConfigTest : public ::testing::Test {
protected:
std::unique_ptr<ParseTreeInterface<std::string>> treeMock;
virtual void SetUp() {
treeMock = ParseTreeMock<std::string>::getDefaultTree();
}
};
And I want to set return specific value on getProperty method:
EXPECT_CALL(*treeMock, getProperty("miniReaderConfig.cacheConfig.cacheOnOff")).willOnce(Return(false));
I get error:
In file included from ./lib/googletest/googlemock/include/gmock/gmock-generated-function-mockers.h:43:0,
from ./lib/googletest/googlemock/include/gmock/gmock.h:61,
from ./test/UT/Mocks/ParseTreeMock.hpp:2,
from test/UT/Configuration/ConfigTest.cpp:1:
test/UT/Configuration/ConfigTest.cpp: In member function ‘virtual void ConfigTest_CreateConfigurationWithoutErrors_Test::TestBody()’:
./lib/googletest/googlemock/include/gmock/gmock-spec-builders.h:1844:12: error: ‘class miniReader::Configuration::ParseTreeInterface<std::__cxx11::basic_string<char> >’ has no member named ‘gmock_getProperty’; did you mean ‘getProperty’?
((obj).gmock_##call).InternalExpectedAt(__FILE__, __LINE__, #obj, #call)
Any solution with explanation of error appreciated.
The treeMock variable needs to be of type std::unique_ptr<ParseTreeMock<std::string>>, and then static method needs to look like this
static std::unique_ptr<ParseTreeMock<T>> getDefaultTree()
{
return std::make_unique<ParseTreeMock<T>>();
}
Typically you instantiate a class that implements an interface in your test and then pass the instance to the class that you are testing, and with EXPECT_CALLs you make sure that the class you are testing calls the callbacks on your mock object.
Not related to the error you got, but WillOnce needs to be spelled with the first letter capitalized. Also, since you set the template variable to std::string, the EXPECT_CALL can't expect that a boolean is returned.
This compiles for me:
namespace pt { struct ptree {};}
template<typename T>
class ParseTreeInterface
{
public:
virtual void fillConfigTree(std::string const&) = 0;
virtual T getProperty(std::string const&) = 0;
};
template<typename T>
class ParseTreeMock : public ParseTreeInterface<T> {
public:
MOCK_METHOD1(fillConfigTree, void(std::string const&));
MOCK_METHOD1_T(getProperty, T(std::string const&));
ParseTreeMock(): parseTree(std::make_unique<pt::ptree>()) {
}
static std::unique_ptr<ParseTreeMock<T>> getDefaultTree()
{
return std::make_unique<ParseTreeMock<T>>();
}
private:
std::unique_ptr<pt::ptree> parseTree;
};
class ConfigTest : public ::testing::Test {
protected:
std::unique_ptr<ParseTreeMock<std::string>> treeMock;
virtual void SetUp() {
treeMock = ParseTreeMock<std::string>::getDefaultTree();
}
};
TEST_F(ConfigTest, test)
{
EXPECT_CALL(*treeMock, getProperty("miniReaderConfig.cacheConfig.cacheOnOff")).WillOnce(::testing::Return(""));
}
I've been learning C++ and trying to implement various idioms from other languages I'm familiar with.
Recently I've tried to implement a central EventDispatcher which multiple objects can register events that can take N number of arguments, and a single call to EventDispatcher::dispatch(event_name) would call all registered event callbacks.
First I created a template class for Event;
template <typename ..._args>
class Event
{
public:
//Alias for template callback
using _callback = std::function<void(_args...)>;
//Ctor & Dtor
explicit Event(std::string const& name, _callback const& cb) : _name(name), _cbFunc(cb) {}
~Event() {}
//Accessors
std::string const& getName() const { return this->_name; }
//Methods
void trigger(_args... a) { this->_cbFunc(a...); }
private:
//Event identifier
std::string _name;
//Event callback - can't be changed inside event.
_callback const _cbFunc;
};
With this structure I can define events like in the following example:
void testCallback(int a) {
std::cout << a << std::endl;
}
Event<int> _event("TestEvent", std::bind(&testCallback, _1));
_event.trigger(20); //This will actually output 20 to the console.
What I want to do next is, have an EventDispatcher class which should be defined like:
class EventDispatcher
{
public:
EventDispatcher();
~EventDispatcher();
void registerEvent(**Event of any type**);
void dispatchEvent(std::string const& eventName, ....args);
private:
std::map<std::string, std::vector<**Event of any type**>> _eventList;
};
so that I can make calls like this;
EventDispatcher _dispatcher;
_dispatcher.registerEvent(_event); //event defined in the previous example.
_dispatcher.dispatchEvent("TestEvent", 20); //this should call event's trigger() method with arguments passed to it actually.
However I couldn't figure out how to implement a central dispatcher and have it be able to register templatized event instances, and then pass variable number of arguments to dispatchEvent(...) and make it trigger all events in a vector of templatized events.
How can I achieve such functionality? Is my thought proccess correct or far from c++ way of implementing such a system? Any tips would be welcome.
I suggest a solution with an abstract base class (IEvent) for the event class (Event)
and a template dispatcher method with variadic arguments and a dynamic_cast.
Apstrac base class with the abstract method getName:
class IEvent
{
public:
virtual const std::string & getName() const = 0;
};
Your event class derived from IEvent:
template <typename ..._args>
class Event : public IEvent
{
public:
//Alias for template callback
using _callback = std::function<void(_args...)>;
//Ctor & Dtor
//template< typename T_CB >
explicit Event( const std::string & name, const _callback & cb ) : _name(name), _cbFunc(cb) {}
~Event() {}
//Accessors
virtual const std::string & getName() const override { return this->_name; }
//Methods
void trigger(_args... a) { this->_cbFunc(a...); }
private:
//Event identifier
std::string _name;
//Event callback - can't be changed inside event.
_callback const _cbFunc;
};
The dispatcher with the template method:
class EventDispatcher
{
public:
EventDispatcher() {}
~EventDispatcher()
{
for ( auto el : _eventList )
{
for ( auto e : el.second )
delete e;
}
}
void registerEvent( IEvent *event )
{
if ( event )
_eventList[event->getName()].push_back( event );
}
template <typename ..._args>
void dispatchEvent( const std::string & eventName, _args...a )
{
auto it_eventList = _eventList.find( eventName );
if ( it_eventList == _eventList.end() )
return;
for ( auto ie : it_eventList->second )
{
if ( Event<_args...> * event = dynamic_cast<Event<_args...>*>( ie ) )
event->trigger( a... );
}
}
private:
std::map<std::string, std::vector<IEvent*>> _eventList;
};
And finally the application:
void testCallback(int a) {
std::cout << a << std::endl;
}
int main()
{
EventDispatcher eventDisp;
eventDisp.registerEvent( new Event<int>( "TestEvent", &testCallback ) );
eventDisp.dispatchEvent( "TestEvent", 20 );
return 0;
}