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
).