GMock doesn't match EXPECT_CALL - c++

I have a mocked function that when I run in a unit test with the anything matcher ('_') the unit test fails because GMock can't find a matched function.
Here is my mocked class and function:
class MockedClass {
public:
MockedClass() {};
~MockedClass() {};
MOCK_METHOD1(unregisterClient, bool(const ThriftClient& tClient));
};
class ConnectionClass {
public:
ConnectionClass() {};
~ConnectionClass() {};
bool unregisterClient(ThriftClient& tClient)
{
bool ret = false;
if (mock_ != NULL)
ret = mock_->unregisterClient(tClient);
return ret;
}
static MockedClass *mock_;
};
MockedClass *ConnectionClass::mock_ = NULL;
Here is the function under test:
class RealObject {
public:
RealObject(ConnectionClass &cc);
void unregister();
private:
ConnectionClass &cc_;
ThriftClient tClient_;
}
RealObject::RealObject(ConnectionClass &cc) {
cc_ = &cc;
}
void RealObject::unregister() {
cc_->unregisterClient(tClient_);
}
Here is the test function:
TEST_F(Test, UnregisterTest) {
MockedClass mclass;
ConnectionClass cc;
cc.mock_ = &mclass;
RealObject obj(cc);
EXPECT_CALL(mclass, unregisterClient(_)).WillOnce(Return(true));
obj.unregister(); // Calls mocked function
}
Here is the failure message:
Test.cpp:142: Failure Actual function call count doesn't match
EXPECT_CALL(mclass, unregisterClient(_))...
Expected: to be called once
Actual: never called - unsatisfied and active
I have also tried:
EXPECT_CALL(mclass, unregisterClient(Matcher<const ThriftClient&>(_))).WillOnce(Return(true));
EXPECT_CALL(mclass, unregisterClient(An<const ThriftClient&>())).WillOnce(Return(true));
All with the same failure message.
Why am I getting this failure message? I don't understand why GMock can't match the function call.

Related

ESP home using Arduino library

I am about to write a custom ESPHome component. I don't have much experience with C language and I am facing some troubles using external library.
For demonstration, I prepared a simple component class..
class Test: public Component {
public:
auto t = timer_create_default();
void setup() override {
ESP_LOGD("TEST", "Test setup called!");
t.every(1000, TestLog);
}
void loop() override {
ESP_LOGD("TEST", "Test loop called!");
t.tick();
}
bool TestLog(void *) {
ESP_LOGD("TEST", "TestLOG!");
return true;
}
}
With this, I receive:
In file included from src\main.cpp:32:0: src\Test.h:7:35: error:
non-static data member declared 'auto'
auto t = timer_create_default();
I took it from some example where they did not have the class, but I can't find out, how to use it.
The library is:
https://github.com/contrem/arduino-timer/
I can still rewrite it without this timer completely and handle it only in the loop function, but I would like to understand what I am doing wrong.
If I change the return type to Timer<> I got another error:
src\Test.h: In member function 'virtual void Test::setup()':
src\Test.h:11:24: error: no matching function for call to
'Timer<>::every(int, )'
t.every(1000, TestLog);
You can not use auto to declare non-static member variables so you need to replace auto with the type returned by timer_create_default().
If you are not sure what type it returns, you can simply use decltype in the declaration:
decltype(timer_create_default()) t = timer_create_default();
If I read the code in the repo correctly, the returned type is Timer<>, so this should also work:
Timer<> t = timer_create_default();
or simply:
Timer<> t;
Also: The function pointer passed to t.every() should be a bool (*)(void*) but TestLog is a non-static member function and the pointer type is bool (Test::*)(void*) - You can fix that by making TestLog static:
class Test: public Component {
public:
// ...
static bool TestLog(void *) {
ESP_LOGD("TEST", "TestLOG!");
return true;
}
};
If you want to get the Test instance in the TestLog callback, make the Timer
Timer<TIMER_MAX_TASKS, millis, Test*> t;
and change TestLog:
class Test: public Component {
public:
// ...
static bool TestLog(Test* t) {
ESP_LOGD("TEST", "TestLOG!");
return true;
}
};
and in setup():
t.every(1000, TestLog, this);
You'll now get a pointer to the Test instance in the TestLog callback and you can use this to call a non-static member function in Test.
Full example:
class Test : public Component {
public:
Timer<TIMER_MAX_TASKS, millis, Test*> t;
void setup() override {
ESP_LOGD("TEST", "Test setup called!");
// call the static member function every second:
t.every(1000, TestLogProxy, this);
}
void loop() override {
ESP_LOGD("TEST", "Test loop called!");
t.tick();
}
bool TestLog() {
ESP_LOGD("TEST", "TestLOG!");
return true;
}
static bool TestLogProxy(Test* t) {
// forward the callback call to the non-static member function:
return t->TestLog();
}
};

Gmock function calls are not called

Gmock doesn't work as exected.
EXPECT_CALL doesn't call mock functions.
Here is the code snippet:
In Header.hpp:
typedef MockITest ITest;
Class mainclass
{
public:
std::shared_ptr<ITest> mTestCtrl;
funcToTest();
};
source.cpp
{
std::shared_ptr<mainclass> mainclassPtr;
funcToTest()
{
mTestCtrl = getCtrl();
if( nullptr != mTestCtrl){
cout<< "I can see print here";
mTestCtrl->start();
}
}
}
samplemock.h
class MockITest
{
public:
/// #brief function mock
MOCK_METHOD0(start, void());
};
std::shared_ptr<MockITest> getCtrl()
{
return std::make_shared<MockITest>();
}
test.cpp
TEST_F(TestMqttgwProcessKeepAlive, Test_funcToTest)
{
mainclassPtr = std::make_shared<mainclass>();
mainclassPtr->funcToTest();
EXPECT_CALL(*mainclassPtr->mTestCtrl.get(), start()).Times(1);
}
I get this error.
Uninteresting mock function call - returning directly.
Function call: start()
Actual function call count doesn't match EXPECT_CALL(*mainclassPtr->mTestCtrl.get(), start())...
Expected: to be called once
Actual: never called - unsatisfied and active
I think you should put EXPECT_CALL before the call to funcToTest:
TEST_F(TestMqttgwProcessKeepAlive, Test_funcToTest)
{
mainclassPtr = std::make_shared<mainclass>();
EXPECT_CALL(*mainclassPtr->mTestCtrl.get(), start()).Times(1);
mainclassPtr->funcToTest();
}
In general, expectations should come first, then calls to the functions that are expected to be called.

Using EXPECT_CALL for local methods

I know EXPECT_CALL is supposed to be used for mocked classes and their objects/methods. But is it ever possible to use this to expect calls of local methods?
void Sample::Init()
{
// some codes here...
auto enabled = isFeatureEnabled();
//some other things here
}
bool Sample::isFeatureEnabled()
{
return lights_ and sounds_;
}
I want to EXPECT_CALL isFeatureEnabled() - is this at all possible?
You can try this, I find this approach useful:
class template_method_base {
public:
void execute(std::string s1, std::string s2) {
delegate(s1 + s2);
}
private:
virtual void delegate(std::string s) = 0;
};
class template_method_testable : public template_method_base {
public:
MOCK_METHOD1(delegate, void(std::string s));
};
TEST(TestingTemplateMethod, shouldDelegateCallFromExecute) {
template_method_testable testable_obj{};
EXPECT_CALL(testable_obj, delegate("AB"));
testable_obj.execute("A", "B");
}

How to return a specific value every nth time of a consecutive call with Gmock

In the code Google Mock test snippet there is an EXPECT_CALL that returns True and an argument reference for 200 times.
How can I let the test only return True every nth time. For example return True each 10th call and otherwise return False.
class MockHandler : public Handler
{
public:
MOCK_METHOD1(RxMsg, bool(Msg &msg));
}
TEST(TestDispatcher, HandlePing)
{
auto mockedHandler = make_unique<MockHandler>();
Msg rxMsg = { REQUEST::REQ_PING, sizeof(DefaultMsg_t), rxMsg.rx,(uint8_t*)"0"};
EXPECT_CALL(*mockedHandler,
RxMsg(_)).Times(checkValue).WillRepeatedly(
DoAll(SetArgReferee<0>(rxMsg), Return(TRUE)));
Dispatcher dispatcher(10, mockedHandler);
for (int i = 0; i < 199; i++)
{
dispatcher.RunToCompletion();
}
}
There are few approaches that might work for you. I like the solution with Invoke as a default action, because it is the most flexible. You didn't provide mcve in your question, so I wrote very simple implementations for the classes you use. Also you made a mistake using unique_ptr for the mock. In 99% of cases is must be shared_ptr, because you are sharing it between testing environment and your System Under Test.
class Msg {};
class Handler {
public:
virtual bool RxMsg(Msg &msg) = 0;
};
class MockHandler: public Handler
{
public:
MOCK_METHOD1(RxMsg, bool(Msg &msg));
};
class Dispatcher {
public:
Dispatcher(std::shared_ptr<Handler> handler): h_(handler) {}
void run() {
Msg m;
std::cout << h_->RxMsg(m) << std::endl;
}
private:
std::shared_ptr<Handler> h_;
};
class MyFixture: public ::testing::Test {
protected:
MyFixture(): mockCallCounter_(0) {
mockHandler_.reset(new MockHandler);
sut_.reset(new Dispatcher(mockHandler_));
}
void configureMock(int period) {
ON_CALL(*mockHandler_, RxMsg(_)).WillByDefault(Invoke(
[this, period](Msg &msg) {
// you can also set the output arg here
// msg = something;
if ((mockCallCounter_++ % period) == 0) {
return true;
}
return false;
}));
}
int mockCallCounter_;
std::shared_ptr<MockHandler> mockHandler_;
std::unique_ptr<Dispatcher> sut_;
};
TEST_F(MyFixture, HandlePing) {
configureMock(10);
for (int i = 0; i < 199; i++) {
sut_->run();
}
}
At the beginning of each test you should call configureMock method that will Invoke ON_CALL macro setting the default action for your mock. Function passed to Invoke can be any function matching the signature of the method you are overwriting. In this case it;s a function that counts how many times mock has already been called and returns appropriate value. You can also assign some particular object to the msg output argument.

How to match argument reference in Google Mock

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.