I'm trying to mock a static function member with gmock. I found a section on the gMock Cookbook that talks about Mocking Free Functions. However it is not clear to me..
For instance, I have a static function called isActiveMode that I want to mock. Instead of calling isActiveMode directly, I have to introduce an interface for it and have a concrete subclass that calls the static function:
class MyClassInterface {
public:
...
virtual bool isActive() = 0;
};
class MyClass: public MyClassInterface {
public:
...
virtual bool isActive()
{
return isActiveMode();
}
};
Then I define the mock class:
class MyMock {
public:
MOCK_METHOD(bool, isActive, (), (override));
};
But this does not seem to work..
Does somebody have a clue on how to make this work?
Your mock class should be derived from the interface class.
class MyMock : public MyClassInterface {
public:
MOCK_METHOD(bool, isActive, (), (override));
};
If that doesn't help, please provide a minimum reproducible example showing how you are using the mock.
Related
I am learning mocking and using googletest I created MockServer class that should mock the abstract class IServer:
class IServer
{
virtual void writeData(QString buffer) = 0;
virtual QByteArray readData() = 0;
protected:
virtual ~IServer() = default;
};
class MockServer: public:: testing:: Test, public IServer
{
MOCK_METHOD(void, writeData, (QString buffer), (override));
MOCK_METHOD(QByteArray, readData, (), (override));
};
And now want to test the other class that uses it, however, I cannot initialize MockServer because it is an abstract class. How to solve this?
TEST_F(Serv_test, start)
{
?? MockServer mockServer; // <- how to declare it?
EXPECT_CALL(mockServer, writeData(testing::_)).Times(1);
EXPECT_CALL(mockServer, readData()).Return("testing");
Car car (nullptr, mockServer);
}
You are confusing a few things:
You are using a test fixture, but a test fixture needs to be a standalone class. You are mixing it with your mock class. You need to create a separate class for it.
The Car class should take a parameter of type mock class (not the test fixture).
.Return should be used inside WillOnce or WillRepeatedly among other places. You can't use it directly on EXPECT_CALL.
I rewrote your code as follows:
class IServer
{
public:
virtual void writeData(QString buffer) = 0;
virtual QByteArray readData() = 0;
protected:
virtual ~IServer() = default;
};
// Test fixture
class Serv_test : public ::testing::Test {
};
// Mock class
class MockServer: public IServer
{
public:
MOCK_METHOD(void, writeData, (QString buffer), (override));
MOCK_METHOD(QByteArray, readData, (), (override));
};
class Car{
public:
Car(int*, IServer* server):_server(server){
_server->writeData("testing");
_server->readData();
}
IServer* _server;
};
TEST_F(Serv_test, start)
{
MockServer mockServer; // <- how to declare it?
EXPECT_CALL(mockServer, writeData(testing::_)).Times(1);
EXPECT_CALL(mockServer, readData())
.WillOnce(testing::Return("testing"));
Car car (nullptr, &mockServer);
}
Working example here: https://godbolt.org/z/avsKdh37r
I am having difficulties in figuring out how to mock the singleton class, and test it in another class. The goal is to verify that a method from a singleton class (Alarm) gets called from another class (CEvnts).
I was able to test this successfully by eliminating the singleton function, but since it is legacy code, I cannot change the structure.
Going through several articles and posts online, I have not found a clear answer. Does anyone know how to set up the Google Test for a singleton class? Any references or articles can be a big help.
Singleton Class:
class Alarm
{
public:
Alarm();
virtual ~Alarm();
// Singleton
static Alarm* find(void)
{
if (!Alarm_Instance)
{
Alarm_Instance = new Alarm();
}
return Alarm_Instance;
}
// Member methods
virtual ENUM_TYPE getType(ENUM_TYPE ENUM_ARG);
private:
static Alarm* Alarm_Instance;
};
ENUM_TYPE Alarm::getType(ENUM_TYPE ENUM_ARG)
{
return aMatch[ENUM_ARG].aType;
}
Mock:
class Alarm_Mock : public Alarm
{
public:
Alarm_Mock();
virtual ~Alarm_Mock();
MOCK_METHOD1(getType, ENUM_TYPE(ENUM_TYPE ENUMONE));
};
Google Test:
class Ev_test: public testing::Test
{
void SetUp()
{
mpsEV= new CEvents();
ON_CALL(msMock, getType(_)).WillByDefault(Return(SOME_ENUM));
}
void TearDown()
{
delete mpsEV;
}
protected:
Alarm_Mock msMock;
CEvents* mpsEV;
};
TEST_F(Ev_test, testGetFunctions)
{
EXPECT_CALL(msMock, getAlarmType(_))
.Times(1);
mpsEV->aMethod(arg1, arg2, arg3, arg4);
}
Class Method to Test - Does getType from Class Alarm get called?:
void CEvents::aMethod(arg1, arg2, arg3, arg4)
{
Alarm::find()->getType(arg1);
}
CEvents::aMethod() invokes getType(arg1) on the instance returned by Alarm::find(), which will be different from your mock object.
A quick fix would be to move the assignment of Alarm::Alarm_Instance out of Alarm::find() and into Alarm::Alarm().
I have a class that is subclass of an external class over which I don't have any control. The external class depend on system resources. For example
class MyClass : public ExternalBase // This class is from external framework and framework requires it to derive from this class.
{
int doSomePrivateThing(int );
public:
virtual int DoSomething(int );
virtual ~MyClass();
}
int MyClass::doSomePrivateThing(int )
{
// do some private task
}
int MyClass::DoSomething(int n)
{
// Do MyClass Specific task
int k = doSomePrivateThing(n);
return ExternalBase::DoSomething(k); // This function depends on external system resources.
// Probably try to communicate with remote server
// or attempt access Storage or Display device etc.
}
MyClass::~MyClass()
{}
How can I break the dependency of MyClass and write unit test for MyClass::DoSomething(). Using composition in place of inheritance is not a choice as framework requires classes to be derived from this base class.
I am using C++ and GoogleTest/Mock. But any generalized solution is appreciated.
Thanks in advance.
There are two ways. I call them "a little more correct" way and "very ugly" way.
The "more correct" way:
Enclose external class functions with some additional layer than can be partial mocked.
class MyClass : public ExternalBase // This class is from external framework and framework requires it to derive from this class.
{
int doSomePrivateThing(int );
public:
virtual void BaseDoSomething(int) { return ExternalBase::DoSomething(v); }
virtual int DoSomething(int v);
virtual ~MyClass();
};
int MyClass::DoSomething(int n)
{
// Do MyClass Specific task
int k = doSomePrivateThing(n);
return BaseDoSomething(k);
}
And partial mock in UT in this way:
class TestableMyClass : public MyClass
{
public:
using MyClass::MyClass;
MOCK_METHOD1(BaseDoSomething, int(int));
};
TEST(A,A)
{
TestableMyClass objectUnderTest;
EXPECT_CALL(objectUnderTest, BaseDoSomething(112));
objectUnderTest.DoSomething(112);
}
When you need to call also the true base class method in your test - use WillOnce(Invoke...) with EXPECT_CALL.
The "very ugly" way:
Provide your own UnitTest implementation of ExternalBase and link it to your test. This "UnitTest" impolementation of ExternalBase should be based on some global Mocks objects.
ExternalBaseMock.hpp:
class ExternalBaseMock
{
public:
MOCK_METHOD1(DoSomething, int(int));
};
extern ExternalBaseMock externalBaseMock;
ExternalBaseMock.cpp:
ExternalBaseMock externalBaseMock;
int ExternalBase::DoSomething(int n)
{
return externalBaseMock.DoSomething(n);
}
Then your tests:
#include "ExternalBaseMock.hpp"
TEST(A,A)
{
MyClass objectUnderTest;
EXPECT_CALL(externalBaseMock, DoSomething(112));
objectUnderTest.DoSomething(112);
}
I have see some sample code about gmock,
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <stdio.h>
#include <string>
class MockFoo {
public:
MockFoo() {}
MOCK_METHOD3(Bar, char(const std::string& s, int i, double x));
MOCK_METHOD2(Bar2, bool(int x, int y));
MOCK_METHOD2(Bar3, void(int x, int y));
private:
GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo);
};
class GMockOutputTest : public testing::Test {
protected:
MockFoo foo_;
};
TEST_F(GMockOutputTest, ExpectedCall) {
testing::GMOCK_FLAG(verbose) = "info";
EXPECT_CALL(foo_, Bar2(0, _));
foo_.Bar2(0, 0); // Expected call
testing::GMOCK_FLAG(verbose) = "warning";
}
The mock class MockFoo is mocking three functions as is in the class body, but the class MockFoo does not inherit any class.
If I understand it correctly, the mock class can mock virtual and non-virtual functions.
1) Mocking virtual functions: mock class should inherit a base class being mocked, and all the functions in that class should be virtual, but in this example, there is no base class.
2) Mocking non-virtual functions: mock class does not need inherit any class, but it needs to add tamplate to the code in order to use hi-perf dependency injection.
Does the code above belong to any of the case? And what is it trying to mock? And how to understand it?
The key thing to remember here is that a mock class can override either virtual or non-virtual methods in a superclass, but it doesn't have to. Sometimes it's useful to define a totally standalone mock which doesn't conform to any particular interface or override any other functionality. Consider the case where you are testing a templatized class:
template <typename T>
class Foo {
public:
Foo(T* member) : _member(member) {}
void f() { _member->bar(); }
private:
T* _member;
};
You want to verify that class Foo invokes bar() on the template parameter class, but the template class doesn't need to conform to any formal interface; it just needs to expose a bar() method. In this case you might use a standalone mock:
class MockSomething {
public:
MOCK_METHOD0(bar, void());
};
Just like your example, this mock class has no relationship to another class or interface. It's a standalone mock, and it can be used just as you would any other:
TEST(StackOverflow, StandaloneMock) {
MockSomething mock;
EXPECT_CALL(mock, bar());
Foo<MockSomething> foo(&mock);
foo.f();
}
That code is to test the method Bar2() of template class NaggyMock. To be more precise, it is testing that when you call method Bar2() with parameters 0 and 0, that Bar2() method from the mock is going to be called.
You can look at that as a static dependency injection, since you inject dependency through a template parameter. I would say it is the case 2.
Assuming your template class NaggyMock looks like this :
template< typename Foo >
class NaggyMock
{
public:
bool Bar2(int x, int y)
{
if ( ( 0 == x ) && ( 0 == y ) )
{
return foo.Bar2( 0, 11 );
}
return false;
}
private:
Foo foo;
};
then in the unit test you are testing the case when both parameters are 0. If your real class is using some resource (reading from a network, or from a database, or a file, ...), then to avoid it, and make your unit test very fast, you are going to mock that object. And that is what you are doing. Instead of the class handing the real resource, you are injecting a mock object.
For more information, read :
What is Mocking?
Why prefer template method over dependency injection?
Using Visual Studio 2010 C++ with GMock. Trying to create a stub object for a third party class that is used by my classes but I'm getting the following error:
Error: object of abstract class type
"ThirdPartyClassFake " is not allowed.
The third party class is defined like:
namespace ThirdPartyNamespace
{
class __declspec(novtable) ThirdPartyClass : public ThirdPartyBaseClass
{
public:
virtual bool Hello() const = 0;
virtual bool Goodbye() const = 0;
};
}
I created a mock of this:
namespace ThirdPartyNamespace {
class ThirdPartyClassFake : public ThirdPartyClass {
public:
MOCK_CONST_METHOD0(Hello, bool());
MOCK_CONST_METHOD0(Goodbye, bool());
};
}
Now in my test I'm trying to do:
TEST(MyService, WhenCalled_DoesTheRightThingTM) {
// Arrange
ThirdPartyClassFake stub;
// Act
...
// Assert
...
}
The error is on the "ThirdPartyClassFake stub;" line. Why am I getting this error and how can I successfully create a mock/stub object?
Specifically the problem was that although I implemented ThirdPartyClass's virtual methods in my mock object, I neglected to implement ThirdPartyBaseClass's virtual methods. This was causing the error. Once I added MOCK_METHOD calls for those methods the error went away.
Class ThirdPartyClass is an abstract class ( two pure virtual member functions ). Any class that derives from it must override/implement the virtual methods.