I'm making a mock class of istream to test a class. But the mocked object is not passing to the actual class i want to use in.
This is the mock class.
class MockStream{
private:
std::string filename_;
public:
MockStream(){
}
MockStream(std::string filename, std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out):filename_(filename){
}
MockStream(const MockStream &a){}
MockStream& operator=(const MockStream& a){
return *this;
}
~MockStream(){}
MOCK_CONST_METHOD0(is_open,bool());
MOCK_METHOD0(close,void());
MOCK_METHOD2(read,MockStream&(char*,std::streamsize));
MOCK_METHOD2(write,MockStream&(const char*,std::streamsize));
MOCK_METHOD2(seekg,MockStream&(std::streamoff,std::ios_base::seekdir));
MOCK_METHOD1(seekg,MockStream&(std::streampos));
MOCK_METHOD0(get_filename,std::string());
};
test:
TEST(random_access_stack, mocked_test)
{
RandomAccessStack<TestClass,u_int64_t,MockStream> stack;
MockStream mocked;
EXPECT_CALL(mocked,is_open()).Times(1).WillOnce(testing::Return(true));
stack.SetStream(mocked);
EXPECT_TRUE(stack.is_open());
}
SetStream function:
void SetStream(STREAM& handle){
file_handle_ = handle;
}
where file_handle_ is of type MockStream passed by template
The output is:
GMOCK WARNING:
Uninteresting mock function call - returning default value.
Function call: is_open()
Returns: false
NOTE: You can safely ignore the above warning unless this call should not happen. Do not suppress it by blindly adding an EXPECT_CALL() if you don't mean to enforce the call. See https://github.com/google/googletest/blob/master/googlemock/docs/CookBook.md#knowing-when-to-expect for details.
/build/libs/storage/tests/gtest/random_access_stack_tests.cpp:79: Failure
Value of: stack.is_open()
Actual: false
Expected: true
/build/libs/storage/tests/gtest/random_access_stack_tests.cpp:73: Failure
Actual function call count doesn't match EXPECT_CALL(mocked, is_open())...
Expected: to be called once
Actual: never called - unsatisfied and active
Related
I'm writing program to test my c++ function but I couldn't use mock function that has to return another object. I don't know how to resolve it.
So if somebody can help me.
Each time, I get this message on my result's tests:
GMOCK WARNING:
Uninteresting mock function call - returning default value.
Function call: getEventFree()
Returns: NULL
Mock function:
class MockXF : iXF
{
public:
MOCK_METHOD(Event *, getEventFree, (), (override));
};
Button function:
class Button
{
public:
init(*iXF theXF){ixf = theXF}
start(){ixf->getEventFree(); //Use the event ...}
private:
iXF* ixf;
};
Tests:
Event event;
MockXF mockxf;
// will create a segmentation fault which break the test
TEST_F(ButtonTest, Start)
{
Button button(&mockxf);
EXPECT_CALL(mockxf, getEventFree()).WillOnce(Return(&event));
button.start(); //This function called mockxf.getEventFree()
}
So I have a class which is calling method from other class, but eventually it will return a string or so
This is my class: Person.cpp
Person::Person(){}
std::string Person::getName(void) {
return namespaceX::namespaceY::StringVal;
}
This is my mock / test class:
class MockPerson : public Person{
public:
typedef ::testing::StrictMock<Person> Strict;
MockPerson() : Person(){}
~MockPerson() override = default;
MOCK_METHOD0(getName, std::string ());
std::string callFunc(){
return Person::getName();
}
This is my test header file:
class PersonTest : public testing::Test {
public:
PersonTest () :
mock(std::make_shared<MockPerson ::Strict>()){}
~PersonTest (void) override = default;
std::shared_ptr<MockPerson ::Strict> mock;
};
This is my test:
#include "testHeader.hpp"
TEST_F(PersonTest , case1)
{
EXPECT_CALL(*mock, getName());
ASSERT_EQ(someString, mock->callFunc());
}
The test setup looks good to me however when I ran the test, it gives me:
Actual function call count doesn't match EXPECT_CALL(*mock, getName())...
Expected: to be called once
Actual: never called - unsatisfied and active
And the values return in the ASSERT statement is just the default value of the string ("").
Is there a way to go through it? I saw online that we should pass in an actual object to the function but in this case a very simple function causes more troubles than complex ones. Any help is appreciated.
First, compiling your example with g++ gives me the following error:
error: 'using element_type = class testing::StrictMock<Person>' {aka 'class testing::StrictMock<Person>'} has no member named 'gmock_getName'
This can be fixed by passing MockPerson as the template parameter for StrictMock, instead of passing Person:
typedef ::testing::StrictMock<MockPerson> Strict;
Second, your declaration of callFunc explicitly calls the getName function of the Person class. This bypasses the mocked version of getName and hence the instrumentation that Google Mock inserts to keep track of the number of function calls. Therefore, you get the assertion failure about the function call count mismatch. This can be fixed by making callFunc call the getName of the current class (MockPerson) instead:
std::string callFunc() { return getName(); }
Third, the mocked getName will return a default-constructed std::string, hence you get the "". You can change the behavior for all tests belonging to PersonTest, by adding this declaration in the PersonTest constructor:
ON_CALL(*mock, getName()).WillByDefault(Return("xyz"));
Or you can set the behavior for individual tests by modifying the EXPECT_CALL declarations to:
EXPECT_CALL(*mock, getName()).WillRepeatedly(Return("xyz"));
For both variants, the assert for your callFunc should then work as expected:
ASSERT_EQ("xyz", mock->callFunc());
I would like to test the method of my system, whose return value partially depends on the return value of the call to some kind of connection interface. In most cases I would like the IConnection to return true upon any kind of call to it's open(_, _) method. Except in one case, when I explicitly test for the condition with failed connection.
Example:
/*
* Some kind of network interface with method `open`
*/
class IConnection {
public:
IConnection() = default;
virtual ~IConnection() = default;
virtual bool open(const std::string& address, int port) = 0;
};
class ConnectionMock: public IConnection {
public:
MOCK_METHOD2(open, bool(const std::string& address, int port));
};
class MySystem {
public:
MySystem() = delete;
MySystem(std::shared_ptr<IConnection> connection): connection_(connection) {}
bool doSth() {
/*
* Do some things, but fail if connection fails
*/
bool connectionStatus = connection_->open("127.0.0.1", 6969);
if (!connectionStatus) {
return false;
}
// do other things
return true;
}
private:
std::shared_ptr<IConnection> connection_;
};
TEST(MySystemShould, returnFalseIfFailedToOpenConnectionAndTrueIfSucceeded) {
auto connectionMock = std::make_shared<NiceMock<ConnectionMock> >();
ON_CALL(*connectionMock, open(_, _)).WillByDefault(Return(true));
MySystem system(connectionMock);
// if I don't specify Times test fill fail, because WillOnce automatically sets Times(1)
EXPECT_CALL(*connectionMock, open(_, _)).Times(AnyNumber()).WillOnce(Return(false));
/*
* Commented code below is not a good solution - after expectation retires
* the test will fail upon subsequent calls
*/
//EXPECT_CALL(*connectionMock, open(_, _)).WillOnce(Return(false)).RetiresOnSaturation();
ASSERT_FALSE(system.doSth());
/*
* Code bellow allows me to avoid the warning
*/
//EXPECT_CALL(*connectionMock, open(_, _)).WillRepeatedly(Return(true));
ASSERT_TRUE(system.doSth());
}
The problems with my current solution is that when the EXPECT_CALL override becomes saturated, even though gmock goes back to the default action specified on ON_CALL, every subsequent call to open(_, _) is causing the following warning:
GMOCK WARNING:
/whatever.cpp:105: Actions ran out in EXPECT_CALL(*connectionMock, open(_, _))...
Called 2 times, but only 1 WillOnce() is specified - taking default action specified at:
/whatever.cpp:103:
even though I'm using NiceMock. I can get rid of the warning by specifying EXPECT_CALL with WillRepeatedly(Return(true)), but this is the duplication of my code in ON_CALL.
I would like to know, how can I override the default action specified with ON_CALL for just one call to IConnection::open, and then go back to the defaults, without causing gmock to print a warning. The perfect solution would be something similar to:
EXPECT_CALL(*connectionMock, open(_, _)).WillOnce(Return(false)).DisableExpectationAfterSaturation();
but it doesn't exist. RetiresOnSaturation doesn't work as I would like, because it fails the test after getting saturated (doesn't match action specified with ON_CALL).
EDIT 2
The DoDefault() - feature comes close to what is asked in the question. It specifies that an action in EXPECT_CALL should go back to the default action specified by ON_CALL:
using ::testing::DoDefault;
// Default action
ON_CALL(*connectionMock, open(_, _)).WillByDefault(Return(true));
// returns true once and then goes back to the default action
EXPECT_CALL(*connectionMock, open(_, _)
.WillOnce(Return(false))
.WillRepeatedly(DoDefault());
Initial answer
If the return value of IConnection::open depends on the parameters you can specify ON_CALL twice but with different arguments (or rather arguments instead of the placeholder):
ON_CALL(*connectionMock, open(_, _)).WillByDefault(Return(true));
ON_CALL(*connectionMock, open("BAD_ADDRESS", 20)).WillByDefault(Return(false));
So any time the mocked method open will be called with arguments "BAD_ADDRESS" and 20, it will return false, and true otherwise.
Here is a simple example:
using ::testing::_;
using ::testing::AnyNumber;
using ::testing::Return;
class A {
public:
virtual bool bla(int a) = 0;
};
class MOCKA : public A {
public:
MOCK_METHOD1(bla, bool(int));
};
TEST(ABC, aBABA) {
MOCKA a;
ON_CALL(a, bla(_)).WillByDefault(Return(false));
ON_CALL(a, bla(1)).WillByDefault(Return(true));
EXPECT_CALL(a, bla(_)).Times(AnyNumber());
EXPECT_TRUE(a.bla(1));
EXPECT_TRUE(a.bla(1));
EXPECT_TRUE(a.bla(1));
EXPECT_FALSE(a.bla(2));
EXPECT_FALSE(a.bla(3));
EXPECT_FALSE(a.bla(4));
}
EDIT 1
I think now I understood the problem and if I did then the solution is very simple:
EXPECT_CALL(*connectionMock, open(_, _))
.Times(AnyNumber())
.WillOnce(Return(true))
.WillRepeatedly(Return(false));
When ConnectionMock::open will be called inside of MySystem::doSth it will once return true and then always return false no matter what the arguments are. In this case you also don't need to specify ON_CALL. Or do you definitely need to specify the actions with ON_CALL instead of EXPECT_CALL?
I have a function like below:
FnCall(request, response);
where request and reply type are of a class - Message. Now I have mocked the method like below:
class MessageMock : public Message
{
public:
MOCK_METHOD2(FnCall, bool(const Message* request, Message*& response));
};
In my test case I have an expect call to FnCall
EXPECT_CALL(mMessageMock, FnCall(::testing::_,::testing::_));
My requirement is to set some dummy value in the request / response argument in function FnCall of type MessageMock - how can I set that?
=======================================================================
I tried the below code:
MessageMock MessageMock1, MessageMock2;
EXPECT_CALL(mMessageMock, FnCall(&mMessageMock1,
&mMessageMock2));
But receive compilation error and even tried with const declaration:
error: no matching function for call to 'gmock_FnCall(MessageMock*, MessageMock*)'
note: candidate is:
note: testing::internal::MockSpec<bool(const Message*, Message*&)>&
note: no known conversion for argument 2 from 'MessageMock*' to 'const testing::Matcher<Message*&>&'
You are doing this wrong. Your expectation is just on mMessageMock so just that object should be mock. (You are expecting on mock instance) if the test is the caller:
mMessageMock.method(...)
you need to provide dummy objects for that call.
Lets say you have interface like this:
class MyInterface{
public:
virtual void method(MyInterface*, MyInterface*) = 0;
};
and you want to check is some method called on that interface. You define mock class and set expectation on that instance of that mock.
class MyMock : public MyInterface{
public:
MOCK_METHOD2(method, void(MyInterface*,MyInterface*);
};
For your test you need to provide Dummy object to complete interface:
class MyDummy : public MyInterface{
public:
void method(MyInterface*, MyInterface*) override{}
};
So, in your test add:
MyMock mock;
MyDummy request, response;
EXPECT_CALL(mock, method(&request, &response));
and if you want to test this without rest of the code. Just call that method on mock instance after you set expectation.
mock.method(&request,&response);
Here I provide dummy values.
EDIT:
Updated to improve usage of dummy objects.
I'm attempting to mock a DB interface call and return a polymorphic data type as a reference using SetArgReferee. The method I'm mocking takes 2 base class reference arguments. While setting the value for the 2nd reference argument in SetArgReferee, a derived class object is used as the value. In the source code under test, the returned 2nd reference argument is again cast to the derived class and used. This seems to be not working properly.
I have a DBInterface that I'm mocking as below.
class DBInterface {
...
public:
virtual void service(Msg& req, Msg& resp, bool flag) = 0;
...
};
class DBInterfaceMock : public DBInterface {
public:
MOCK_METHOD3(service, void(Msg& req, Msg& resp, bool flag));
};
The test mocks this service call using the EXPECT_CALL as shown below
TEST_F(SessionTest, SessionInt) {
DBInterfaceMock mockDb;
Session* session = new Session(mockDb);
// DerivedMsg inherits from Msg and contains a map
DerivedMsg derivedMsg;
// populating the map inside the derivedMsg
// ...
// ...
EXPECT_CALL(mockDb, service(_, _, false))
.Times(1)
.WillDo(SetArgReferee<1>(*(dynamic_cast<Msg*>(&derivedMsg))));
session->init();
....
....
}
On calling the session->init(), I'm expecting that the mocked service call must return the values as populated in derivedMsg. However, the code hits an ASSERT where the map size is 0 even though the value to be returned in the SetArgReferee has been populated correctly.
In the production code, once the service call executes successfully, the reference argument is retrieved by doing a dynamic_cast to the desired derived type as shown below.
service(req, resp, false);
DerivedMsg derivedResp = *(dynamic_cast<DerivedMsg*>(&resp));
uint16_t size = derivedResp.getMap().size(); //returns a 0 size.
Is there a better way of achieving this? It doesn't seem to be working this way.