How to inspect argument to a gmock EXPECT_CALL()? - unit-testing

I'm using Google Mock (gMock) for the first time. Given the following code snippet:
class LinkSignals
{
public:
virtual ~LinkSignals() { }
virtual void onLink(std::string) = 0;
virtual void onUnLink() = 0;
};
class MockLinkSignals : public LinkSignals
{
public:
MOCK_METHOD1(onLink, void(std::string));
MOCK_METHOD0(onUnLink, void());
};
MockLinkSignals mock_signals;
When I execute some test code that causes EXPECT_CALL(mock_signals, onLink(_)) to be run how can I inspect the argument to onLink()?

You would normally use either existing gmock matchers or define your own to check the arguments passed to the mock method.
For example, using the default Eq equality matcher:
EXPECT_CALL(mock_signals, onLink("value_I_expect"))
Or check for sub string say:
EXPECT_CALL(mock_signals, onLink(HasSubstr("contains_this")))
The gmock documentation provides details of the standard matchers that are available, and also describes how to make custom matchers, for example for an integer argument type:
MATCHER(IsEven, "") { return (arg % 2) == 0; }
It is possible to capture an argument to a variable by attaching an action to the expectation, although this can have limited use in the scope of the expectation:
EXPECT_CALL(mock_signals, onLink(_)).WillOnce(SaveArg<0>(pointer))
I'd suggest studying the various matchers and actions available before choosing the best approach for your particular case.

Related

Mock call not being detected

I created a test case with Catch2 and I am trying to use TrompeLoeil for finer testing.
However the mock calls either don't happen at all, or happen but don't seem to be detecting by the framework.
Here is a minimal reproductible example :
class MyRealClass
{
public:
virtual int returnSumOfValues(int a, int b)
{
return a + b;
}
};
class MyMockClass : public MyRealClass
{
public:
MAKE_MOCK2(returnSumOfValues, int(int,int));
};
class MyTestedClass
{
public:
MyTestedClass(MyRealClass* _computeObj)
: computeObj(_computeObj)
{
}
int compute()
{
return computeObj->returnSumOfValues(2,3);
}
MyRealClass* computeObj;
};
TEST_CASE("Testing Trompe L'oeil")
{
auto mock = new MyMockClass();
MyTestedClass testedClass(mock);
int val = testedClass.compute();
CHECK(val == 5);
REQUIRE_CALL(*mock, returnSumOfValues(2,3)).RETURN(5);
}
And here is the error I get from running this test :
------------------------------------------------------------------------------- Testing Trompe L'oeil
------------------------------------------------------------------------------- ../../../src/MEGAAutoTests/UnitTests/control/TransferBatchTests.cpp:164
...............................................................................
../../../src/MEGAAutoTests/UnitTests/main.cpp:38: FAILED: explicitly
with message: No match for call of returnSumOfValues with signature
int(int,int) with.
param _1 == 2
param _2 == 3
I debugged this step by step and the mocked returnSumOfValues() is the one being executed.
However, if I make MyRealClass::returnSumOfValues() not virtual, the mock class is not used at all.
And the error is :
------------------------------------------------------------------------------- Testing Trompe L'oeil
------------------------------------------------------------------------------- ../../../src/MEGAAutoTests/UnitTests/control/TransferBatchTests.cpp:164
...............................................................................
../../../src/MEGAAutoTests/UnitTests/main.cpp:43: FAILED: CHECK(
failure.empty() ) with expansion: false with message: failure :=
"../../../src/MEGAAutoTests/UnitTests/control/TransferBatchTests.
cpp:172 Unfulfilled expectation: Expected
*mock.returnSumOfValues(2,3) to be called once, actually never called
param _1 == 2
param _2 == 3 "
This seems to not be consistent with the official documentation, which states that :
The line MAKE_MOCK2(log, void(int severity, const std::string& msg))
creates a mock function void Logger::log(int, const std::string&). If
MAKE_MOCKn(...) or MAKE_CONST_MOCKn(...) are used to implement a
virtual function from a base class, it is always recommended to add a
third macro parameter override since it gives the compiler an ability
to complain about mistakes.
Recommended, not required. And to give the compiler more information, not to make the test work.
TL, DR
Why is my code sample not working?
Why do I need to make mocked functions virtual when the documentation suggests it is not mandatory?
The issue was that expectations need to be set beforehand.
I though they worked like assertions, checking a state after the code was executed, but this is not the case.
In this case, moving the call solved the problem. Here is the fixed code sample :
TEST_CASE("Testing Trompe L'oeil")
{
auto mock = new MyMockClass();
MyTestedClass testedClass(mock);
REQUIRE_CALL(*mock, returnSumOfValues(2,3)).RETURN(5);
int val = testedClass.compute();
CHECK(val == 5);
}
This is the solution to the first problem, the second one (only virtual functions can be mocked) remains unanswered.

ON_CALL AND EXPECT_CALL on same method with different parameter matchers generates saturated and active error

In this example bellow I will obtain the following behavior:
EXPECT_CALL(barMock, doBar(7))...
Expected arg #0: is equal to 7
Actual: 5
Expected: to be called once
Actual: called once - saturated and active
#include <gmock/gmock.h>
#include <gtest/gtest.h>
class IBar
{
public:
virtual bool doBar(int barParam) = 0;
};
class BarMock : public IBar
{
public:
MOCK_METHOD1(doBar, bool(int));
};
class Foo
{
public:
Foo(IBar& bar_)
: bar{ &bar_ }
{
}
void doFoo()
{
bar->doBar(7);
bar->doBar(5);
}
IBar* bar;
};
class FooBarTest : public ::testing::Test
{
public:
void SetUp() override
{
ON_CALL(barMock, doBar(testing::_)).WillByDefault(testing::Return(true));
}
testing::NiceMock<BarMock> barMock;
};
TEST_F(FooBarTest, OnCallExpectCallSameMethod)
{
Foo foo(barMock);
ON_CALL(barMock, doBar(5)).WillByDefault(testing::Return(true));
EXPECT_CALL(barMock, doBar(7)).WillOnce(testing::Return(true));
foo.doFoo();
}
Google test versions tested:
1.8.0
1.8.1
Is this intended to cause an error?
How does google test sets the
order calls? Does EXPECT_CALL has higher priority only in this
scenario?
Yes, it is intended to be an error. One of the GoogleMock policies is that in case of possible ambiguity it's better to throw an error an make user state his intention explicitly.
Adding EXPECT_CALL macro effectively says "I care about calls of this method". Whenever EXPECT_CALL is set, GoogleMock will try to match every EXPECT_CALL it has seen in reverse order of declaration (so the latest defined expects are matched first).
One of the reasons for this design is to allow overriding less specific expects with more specific ones (e.g. in constructor of test fixture you set less restrictive expects, but for certain tests you want to match more precisely). Documentation.
However, there is a way of "ignoring" already fulfilled expectations by adding .RetiresOnSaturation()
TEST_F(FooBarTest, OnCallExpectCallSameMethod)
{
Foo foo(barMock);
ON_CALL(barMock, doBar(5)).WillByDefault(testing::Return(true));
EXPECT_CALL(barMock, doBar(7))
.WillOnce(testing::Return(true))
.RetiresOnSaturation();
foo.doFoo();
}
RetiresOnSaturation() will make expectations retired after it has been saturated (i.e. called as many time as expected). GoogleMock will skip over retired expectations as long as there are still any non-retired ones (if all of them are retired then it still prints an error).
If you however need to accept calls doBar(5) before doBar(7), then the only way to do so is to define it as expectation as well:
TEST_F(FooBarTest, OnCallExpectCallSameMethod)
{
Foo foo(barMock);
EXPECT_CALL(barMock, doBar(5)).WillRepeatedly(testing::Return(true));
EXPECT_CALL(barMock, doBar(7))
.WillOnce(testing::Return(true))
.RetiresOnSaturation();
foo.doFoo();
}
RetiresOnSaturation() is still needed because of LIFO (last in, first out) processing of expectations.

Google mock: Mocking parent class?

Assume I have a base class:
class Command {
public:
virtual int8_t Execute();
};
with a definition in the base class cpp.
Additionally, I have a child class:
class SpecificCommand: public Command {
public:
int8_t Execute();
};
With the definition:
int8_t SpecificCommand::Execute() {
doSomeStuff();
Command::Execute();
}
How do I mock Command::Execute() but using a SpecificCommand object for tests?
Maybe something like that:
class SpecificCommandMock : public SpecificCommand
{
public:
MOCK_METHOD0(ExecuteMockedMethod, void());
int8_t Execute() override
{
doSomeStuff()
ExecuteMockedMethod();
}
}
Of course you should use SpecificCommandMock in unit tests and set EXPECT_CALL for ExecuteMockedMethod when class under test is expected to call Execute().
In addition I suppose that something could be wrong in design of the application if you have to do such things.
This should not be possible in the way you are expecting. I.e. gtest cannot just replace the part of your code and instead of:
int8_t SpecificCommand::Execute() {
doSomeStuff();
Command::Execute();
}
execute something like:
int8_t SpecificCommand::Execute() {
doSomeStuff();
}
You operate with macroses mainly which are just wrap your code with some other. So the language limitation still in there.
Some options (which don't affect your Command implementation):
if doSomeStuff is a public - override the Execute() with mock class as proposed by trivelt or do it like official docs suggests with ON_CALL declaration in mock constructor
write DummyCommand.cpp which do nothing and by compilation option build it instead of original one. In cmake it's if-else + add_library/add_executable manipulations.
write mock to the library which uses "network access that can not be tested" and link it instead of original one by compilation option. (if-else + target_link_library or even include manipulations in the cmake)
write mock for the network communication backend (web_server, etc)

How to call mock method instead of real method in mockito/Junit

I want to call ClassA.mockMethod() whenever objOfClassB.realMethod() method is invoked.
public class ClassA{
public static int mockMethod(String url, MySql sql){
int res=0
// do work
return ;
}
}
Definition of executeUpdate1()
class Veps{
protected synchronized int realMethod(String url, MySql sql){
----
-----
}
}
public class VepsTest {
public void setUp() throws Exception {
veps = mock(Veps.class);
when(objOfClassA.realMethod(any(String.class), any())).thenReturn(objOfClassB.mockMethod(any(String.class),any()));
}
}
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Invalid use of argument matchers!
2 matchers expected, 4 recorded.
This exception may occur if matchers are combined with raw values:
//incorrect:
someMethod(anyObject(), "raw String");
When using matchers, all arguments have to be provided by matchers.
For example:
//correct:
someMethod(anyObject(), eq("String by matcher"));
the mockito reports the errors clearly:
Invalid use of argument matchers! 2 matchers expected, 4 recorded.
you shouldn't using Matchers in any then* clause. your problem can be fixed as:
when(veps.executeQuery1(any(String.class), any(MySql.class)))
.thenReturn(DBConnection.mockExecuteQuery("??","??"));
when(veps.executeUpdate1(any(String.class), any()))
.thenReturn(DBConnection.mockExecuteUpdate("??","??"));
but another problem appears: why did you need query the result from the database? you can simply take a constant value to fake the result:
when(veps.executeQuery1(any(String.class), any(MySql.class)))
.thenReturn(1);
// ^--- replace the constant 1 with yours
when(veps.executeUpdate1(any(String.class), any()))
.thenReturn(1);
// ^--- replace the constant 1 with yours
you need to see mockito documentation as further before using it in your test.

JUnit for Functions with Void Return Values

I've been working on a Java application where I have to use JUnit for testing. I am learning it as I go. So far I find it to be useful, especially when used in conjunction with the Eclipse JUnit plugin.
After playing around a bit, I developed a consistent method for building my unit tests for functions with no return values. I wanted to share it here and ask others to comment. Do you have any suggested improvements or alternative ways to accomplish the same goal?
Common Return Values
First, there's an enumeration which is used to store values representing test outcomes.
public enum UnitTestReturnValues
{
noException,
unexpectedException
// etc...
}
Generalized Test
Let's say a unit test is being written for:
public class SomeClass
{
public void targetFunction (int x, int y)
{
// ...
}
}
The JUnit test class would be created:
import junit.framework.TestCase;
public class TestSomeClass extends TestCase
{
// ...
}
Within this class, I create a function which is used for every call to the target function being tested. It catches all exceptions and returns a message based on the outcome. For example:
public class TestSomeClass extends TestCase
{
private UnitTestReturnValues callTargetFunction (int x, int y)
{
UnitTestReturnValues outcome = UnitTestReturnValues.noException;
SomeClass testObj = new SomeClass ();
try
{
testObj.targetFunction (x, y);
}
catch (Exception e)
{
UnitTestReturnValues.unexpectedException;
}
return outcome;
}
}
JUnit Tests
Functions called by JUnit begin with a lowercase "test" in the function name, and they fail at the first failed assertion. To run multiple tests on the targetFunction above, it would be written as:
public class TestSomeClass extends TestCase
{
public void testTargetFunctionNegatives ()
{
assertEquals (
callTargetFunction (-1, -1),
UnitTestReturnValues.noException);
}
public void testTargetFunctionZeros ()
{
assertEquals (
callTargetFunction (0, 0),
UnitTestReturnValues.noException);
}
// and so on...
}
Please let me know if you have any suggestions or improvements. Keep in mind that I am in the process of learning how to use JUnit, so I'm sure there are existing tools available that might make this process easier. Thanks!
It is true that if you are using JUnit 3, and you are testing whether a particular exception is thrown or not thrown within a method, you will need to use something like the try-catch pattern you define above.
However:
1) I'd argue that there is a lot more to testing a method with a void return value then checking for exceptions: is your method making the correct calls to (presumably mocked) dependencies; does it behave differently when the class is initialized with a different context or different sets of dependencies, etc. By wrapping all calls to that method, you make it hard to change other aspects of your test.
I'm also generally opposed to adding code and adding complexity if it can be avoided; I don't think it's a burden to have to put a try/catch in a given test when it's checking for exceptions.
2) Switch to JUnit 4! It makes it easy to check for expected exceptions:
#Test(expected=IndexOutOfBoundsException.class)
public void testIndexOutOfBoundsException() {
ArrayList emptyList = new ArrayList();
Object o = emptyList.get(0);
}
If you have the possibility, you should upgrade to JUnit 4.x.
Then your first example can be rewritten to:
#Test(expected=RuntimeException.class)
public void testTargetFunction() {
testObj.targetFunction (x, y);
}
The advantage here is that you can remove you the private UnitTestReturnValues callTargetFunction (int x, int y) method and use JUnit's built in support for expecting exceptions.
You should also test for specific exceptions instead.
Looks like you reimplemented most of JUnit :) In general you don't need to do it. You just call the function you want to call and compare results. If it throws an exception, JUnit will catch if for you and fail the test. If you expect an exception, either you can use the explicit annotation if you are using JUnit 4, or you can use the following pattern:
public void testThrows()
{
try {
obj.DoSth(); //this should throw MyException
assertFail("Expected exception");
} catch (MyException e) {
//assert the message etc
}
}
again, if obj.DoSth() throws a different exception JUnit will fail the test.
So to sum up, I am afraid I believe your approach is overcomplicated, sorry.
please correct me if I am wrong. As I understood from the provided code you're only checking if there may be an exception while executing the function. But you're actually not verifying, if the called functions "works" correctly unless the only way to end in case of an error would be an exception. I suggest writing additional tests like this:
public void testTargetFunctionSomeValue() {
int someValue = 0;
callTargetFunction(someValue, someValue);
assertTrue(verifyTargetFunction(someValue, someValue));
}
public boolean verifyTargetFucntion(int someValue, int someValue) {
// verify that execution of targetFunction made expected changes.
. . . . .
}
and the verifyTargetFunction would acutally check, if calling targetFunction would have made the expected changes - let's say to a database table by returning true or false.
Hope that helps.
Cheers,
Markus