I have interface which is defined as in .h file
namespace diagnostic{
class class1interface{
virtual int readpowerstate()const =0;
virtual int readparameters() = 0;
}
class class1 : public class1interface{
int readpowerstate()const;
int readparameters();}};
in .cc file i have the function
int diagnostic::readparameters(){
if(diagnostic::readpowerstate ==1)
{ //Dothis}
else
{return 0}}
i have to execute the else part since by default the if will get called when i run the program. So i tried to use gmock as follows.
class Mock_class : public diagnostic::class1interface{
public:
Mock_class(){}
MOCK_METHOD0(readparameters,int());
MOCK_CONST_METHOD0(readpowerstate,int());};
and the gmock test i wrote as follows // Test the failure of Read Parameters
TEST_F(TestBase, readParam_failure){
Mock_class mock_class;
class1 *class_dummmy = new class1();
EXPECT_CALL(mock_class, readpowerstate()).WillOnce(Return(0));
class_dummy->readparameters;
EXPECT_EQ(0, class_dummy->readparameters());}
when i'm executing this program i'm getting the error that
error: Actual function call count doesn't match
EXPECT_CALL(mock_class, readpowerstate())
...
Expected: to be called at least once
Actual: never called - unsatisfied and active
what is the solution for this since i'm new to gmock.
Module tests are all about testing an isolated module (like an instance of a selected class) in a mocked environment, specifically, how that module communicates with other objects, and how it responds to various results of these calls. To make this possible, one uses mocks in place of that other real objects. Mock classes allow to both:
This makes it possible to test an object as if it were surrounded by real components, without actually having those. E.g., a device manager can be tested on how it responds to device failures, by mocking a class representing a device and programming that mock to return an error code when some status function is invoked by the manager. That is, no real device class is used, and also, no real (faulty!) device itself is needed to be connected and configured. The mock will pretend to be that device, and what's important, this will all be on a software level.
This, however, is possible only if the class itself is designed in a way that allows us to somehow inject mocked objects in place of their real counterparts. Most importantly, the objects in the system need to communicate via interfaces and virtual calls. That is, the aforementioned device manager should not be communicating with, e.g., DeviceA
(a concrete class name), but instead, some DeviceInterface
, and so both DeviceA
and a newly created mock DeviceMock
could implement that interface and be used in that manager. This way the manager will not even know that it is beeing tested and communicates with a mocked object, and not the real device wrapper.
That is, currently, although you create a mock for class1interface
you don't actually use that mock. Instead, you try to test class1
. Creating a mock for class1interface
is useful only if you aim to test some other component (like a class) that communicates with class1
through class1interface
, not class1
itself.
So, having a mock for class1
, you can e.g. test class2
. But this requires this class design to meet the conditions I mentioned previously: communicating via interfaces and ability to inject a mock class.
So to meet the conditions, you'd have to rewrite the code:
int class2::readdata()
{
std::unique_ptr<diagnostic::class1interface> classint
= std::make_unique<diagnostic::class1>();
int value = classint->readparameters();
return value;
}
to (it's just an example of questionable usefulness, you'd have to adjust it to your needs):
int class2::readdata(diagnostic::classinterface* classint)
{
int value = classint->readparameters();
return value;
}
And so you could write a test for class2
, injecting a mock of class1
:
TEST_F( TestClass2, readParam_failure )
{
// Mocks configuration
Mock_class mock_class;
EXPECT_CALL( mock_class, readparameters() ).WillOnce(Return(0));
// System under test configuration
diagnostic::class2 sut;
// Test itself
EXPECT_EQ( 0, sut.readdata(&mock_class) );
}
This way you check that the call to class2::readdata
is properly fowarded to class1interface::readparameters
, and its result is returned.