How does one verify state for a mock object? - unit-testing

I have a program Foo that runs on a device and first calls method1() and then method2() on an external module Bar.
When both are called, then in response, Bar calls request() on Foo.
To mock Bar, it has a reference to Foo and a method call_Request() which calls foo.request()
// in class BarTest
#Test
public void barFlow() {
InOrder inOrder = inOrder(mockBar);
inOrder.verify(mockBar).method1(anyInt());
inOrder.verify(mockBar).method2();
// what to put as 'thenCallMethod'?
when(mockBar.method2()).thenCallMethod().call_Request();
}
...
// in class Bar
public void call_Request() {
foo.request();
}
I cannot simply put a call to call_Request() in method2 because only when both methods are called in order does the response happen. Other times, different responses may happen.
what Mockito trick will do 'thenCallMethod'?
(I am using the Mockito ver 1.10.19 bundled with Android Studio 2.1)

You seem to have no clear definition of what your unit under test is. There seem to be 3 possiblities:
there are separate tests for Foo and Bar and the unit under test is an instance of Foo using a mock of Bar and an instance of Bar using a mock of Foo
the unit under test is an instance of Foo using a real instance of Bar, but the Bar instance uses a Foo mock
the unit under test is an instance of Foo using a real instance of Bar which in turn uses the existing instance of Foo
In case 1. you could test the following for Bar:
#Test
public void testBar1() {
Foo mockFoo = Mockito.mock(Foo.class);
Bar bar = //obtain unit under test that uses mockFoo
bar.method1(1/*or whatever int value is appropriate*/);
bar.method2();
Mockito.verify(mockFoo).request();
}
#Test
public void testBar1() {
Foo mockFoo = Mockito.mock(Foo.class);
Bar bar = //obtain unit under test that uses mockFoo
bar.method2();
bar.method1(1/*or whatever int value is appropriate*/);
Mockito.verify(mockFoo, Mockito.never()).request();
}
And the test for Foo would look like:
Bar mockBar = Mockito.mock(Bar.class);
Foo foo = //obtain unit under test that uses mockBar
// invoke method on foo that would trigger calls to mockBar
InOrder inOrder = inOrder(mockBar);
inOrder.verify(mockBar).method1(anyInt());
inOrder.verify(mockBar).method2();
In case 2. you would basically repeat the test for Foo from case 1. But you would just verify that Foo.request() was invoked on the mock of Foo used by the instance of Bar. The order of invocations on the Bar instance are not of any interest for this test case.
In case 3. you wouldn't be able to verify any invocations, because there are no mocks used at all.
Using something like
when(mockBar.method2()).thenCallMethod().call_Request();
doesn't make much sense, because you give a mock an implementation, that it might not have in production code.

Related

Calling one TEST_F in another TEST_F in gtest

I have a test suite in gtest.My Test Fixture class has two tests,one is Test_F(functional),Test_F(performance).
I have the implementation in such a way that Test_F(performance) is dependent on the run of Test_F(functional).
I want to handle the case,where when Test_F(functional) is disabled.So,my approach is calling Test_F(functional) from inside Test_F(performance).
I am not sure,how this is done in gtest,calling a test_function,inside another test_function.
Any help is appreciated.
AFAIK there's no option to call test function inside another test function. However, to share the code between test cases, you can define a helper method in the test suite:
class FooBarTestSuite : public ::testing::Test {
public:
TestSuite() {
// init code goes here
// foo and bar are accessible here
}
~TestSuite() {
// deinit code goes here
// foo and bar are accessible here
}
void CommonCode() {
// common test case code here
// foo and bar are accessible here
}
ClassFoo foo{};
ClassBar bar{};
};
TEST_F(FooBarTestSuite, PerformanceTest) {
CommonCode();
// performance-specific code here
}
TEST_F(FooBarTestSuite, FunctionalTest) {
CommonCode();
// functional-specific code here
}
In order to run a specific test case, use --gtest_filter=*Performace* or --gtest_filter=*Functional* as the parameter.

Using spocks method counter on mocks out of compositions?

I have an issue with creating test data with spock framework.
To follow "composition over inheritance", I have a class to create testdata for my unit tests. As a simple snipped it looks like this:
class TestData extends Specification{
Foo createFoo(){
GroovyMock(Foo){
doSomething() >> "MOCKED!"
}
}
}
When I write a Test, i like to test, if and how often the method has been invoked. Like this
def "simple test"(){
given:
TestData testData = new TestData()
Foo foo = testData.createFoo()
when:
println foo.doSomething()
then:
1 * foo.doSomething()
}
I know, this test doesn't makes sense. It's just for illustriating the behavior.
I would expect a "green result" of that test, since doSomething() has been invoked 1 time. But test result is red:
Too few invocations for:
1 * foo.doSomething() (0 invocations)
[...]
When i mock Foo directly, everything works fine :
def "simple test"(){
given:
Foo foo = GroovyMock(Foo){
doSomething() >> "MOCKED!"
}
when:
println foo.doSomething()
then:
1 * foo.doSomething()
}
Anyone has an idea how to treat this without deriving my testclass from TestData?
Btw. I used the stub returning "MOCKED!" to show, the mock works. But its not "overwritten" or whatever it is called, when testData created the mock.
Mocks interactions must be defined inside the Specification that uses them. Importing mocks from other sources like
TestData testData = new TestData()
Foo foo = testData.createFoo()
is not supported.
While it is possible to create mocks outside of a Specification and attach them later on, it is not possible to define interactions outside of a Specification.

Unit testing when the returned value is a mock expectation

So I have a method that looks something like this:
public Foo method() {
...
return service.get();
}
service is an external dependency of the class.
My test code:
Foo mockServiceResponse = Mockito.mock(Foo.class);
when(service.get()).thenReturn(mockServiceResponse);
In my unit test I inject a mock created with Mockito and set a when for service.get() so my question is, how do I test the return value of method?
If I just check if mockServiceResponse is equal to method() the test doesnt check much since if someone changes method to:
public Foo method() {
...
Foo f = service.get();
f.setId(null);
return f;
}
My test will still pass, which is obviously wrong, so how should I test this?
CLARIFICATION: What I want to test is that method doesnt change the object returned from service.get() (meaning, I want the second stub to fail my test), problem is mock objects just ignore methods called on them (like setId()) without failing the test.
You'll do something like:
Service service = mock(Service.class);
Foo aResponse = new Foo(1);
when(service.get()).thenReturn(aResponse);
MyClass subject = new MyClass(service);
Foo result = subject.method();
assertNull(result.getId());
You can use Mockito's verifyNoMoreInteractions or verifyZeroInteractions to assert that no calls were made to the service response object.
#Test
public void should_not_mutate_response() {
// given
Service mockService = Mockito.mock(Service.class);
Foo mockServiceResponse = Mockito.mock(Foo.class);
when(mockService.get()).thenReturn(mockServiceResponse);
SubjectUnderTest subjectUnderTest = new SubjectUnderTest(mockService);
// when
Foo result = subjectUnderTest.method();
//then
Mockito.verifyZeroInteractions(mockServiceResponse);
}
Or if you expect some particular interactions with the response object after all:
#Test
public void should_set_id_on_response() {
// given
...
// when
...
// then
Mockito.verify(mockServiceResponse).setId(ArgumentMatchers.anyInt());
Mockito.verifyNoMoreInteractions(mockServiceResponse);
}

gmock Multiple mock instances, but only one is effective

I would like to test a class (Controller) that manages a set of entities of a certain kind. Entities are created internally in this class because a factory would be an overkill here, so here is how I inject mocks into it:
class TestController : public Controller {
public:
/* Mechanism for a mock injection */
std::shared_ptr<IEntity> create_entity() override {
return temp_entity;
}
/* Variable to hold the entity being injected */
std::shared_ptr<IEntity> temp_entity;
};
Production code invokes create_entity() in the Controller class, which I overload here, and adds the result to a container. temp_entity is the way I supply my mocks and the test, where I supply two distinct mock instances, looks like this:
class MockEntity : public IEntity {
MOCK_METHOD0(perform_operation, bool());
}
TEST(ControllerTest, TestFailure) {
std::shared_ptr<TestController> controller = std::make_shared<TestController>();
std::shared_ptr<MockEntity> entity1 = std::make_shared<MockEntity>();
controller->temp_entity = entity1;
controller->add_entity(); // This invokation fetches the result of create_entity()
std::shared_ptr<MockEntity> entity2 = std::make_shared<MockEntity>();
controller->temp_entity = entity2;
controller->add_entity(); // This invokation fetches the result of create_entity()
EXPECT_CALL(*entity1, perform_operation().WillOnce(::testing::Return(true));
EXPECT_CALL(*entity2, perform_operation().WillOnce(::testing::Return(false));
controller->run();
}
controller.run() only concurrently executes perform_operation() on each of the entities.
When the test is run, the function in the second expectation is called twice and the function in the first expectation is not run at all. I am sure that the controller operates on two distinct versions of an entity before executing run() function.
Is there a fundamental problem in what I am trying to do? How can I separate my expectations for these two mocks in a test? I tried creating two distinct mock classes with perform_operation() method being implemented in the mock body and when running the test in the debugger I still hit the method of one mock class twice.
The test looks correct and the way, how you inject the mocks into the system under test, is an absolutely reasonable method.
I suppose, the critical issue is in your class under Test. I rebuild your Test with the following controller:
class Controller {
public:
virtual std::shared_ptr<IEntity> create_entity() = 0;
void add_entity() {
auto entity = create_entity();
entities.push_back(entity);
}
void run() {
for(auto e : entities) {
bool i = e->perform_operation();
}
}
std::vector<std::shared_ptr<IEntity> > entities;
};
With this class the test succeeded like expected.

Can google mock mock the behavior of changing the out param?

I start using gmock for my code recently, some of which rely on some other outside services or interfaces, so gmock is kind of perfect for me.
Say I have a trivial class A to mock
class A
{
void foo(int& bar) {
// will change bar
bar = GetingResultFromSomeOutsideService();
}
};
Now I create a mock class
class MockA: public A
{
MOCK_METHOD1(foo, void(int& bar));
};
In my test case, I try to mock the behavior of A::foo of changing bar with ON_CALL, but I don't know how exactly.
For example, I want my MockA::foo always set bar to 1, so that my other codes invoking A::foo will always get bar == 1 like this:
// some other piece of codes invoking A::foo
int bar = 0;
A my_a;
my_a.foo(bar);
cout << bar; // always output "1" with gmock
Any hint?