question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

When overriding a stub, the original stub should not be invoked

See original GitHub issue

Situation: I have a test class in which a mock should invoke a custom Answer during most test methods, but a couple test methods need different behavior. So I created a Before method to stub the mocks, then in the relevant test methods, I stub them again to override. The problem is that Mockito invokes the original Answer when I stub the mock the second time, which in my case causes a NPE because the custom Answer is doing things with the invocation parameters.

I’m working around the problem by creating an OverridableAnswer that gets attached to the mock, and delegates to the real Answer. But this creates a bunch of unnecessary boilerplate. It would be nice if Mockito noticed that the stubbed method is being invoked during a new stubbing, and skip calling the originally stubbed Answer.

This issue was discovered on Mockito 1.10.19 (we currently can’t upgrade to 2.x because PowerMock’s support for Mockito 2 is broken), but I confirmed it still exists in 2.2.22.

Here’s a simple reproducer:

	@Test
	public void testOverrideStub() {
		A instance = Mockito.mock(A.class);
		Mockito.when(instance.foo()).then(new Answer<Integer>() {
			public Integer answer(InvocationOnMock invocation) throws Throwable {
				invoked = true;
				return 1;
			}
		});
		Mockito.when(instance.foo()).then(new Answer<Integer>() {
			public Integer answer(InvocationOnMock invocation) throws Throwable {
				return 2;
			}
		});
		Assert.assertFalse("Overriding stubbing should not invoke original stub", invoked);
	}
	
	private static class A {
		public int foo() {return 0;}
	}

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:8 (4 by maintainers)

github_iconTop GitHub Comments

3reactions
haartscommented, May 2, 2017

Sorry to comment on this closed issue. But I can’t seem to grok this. I have simple test class which defines a @Before method. Therein I mock a certain call. This mock is good for all but two of my @Tests. That looks something like this:

    @Before public void stubTanks() {
        when(tankRepository.findAll())
                .thenReturn(new HashSet<>(Arrays.asList(new Tank())));
    }

In the two deviates I overwrite (or so I thought) the stub like so:

    doReturn(new HashSet<>(Arrays.asList(new Tank(), new Tank()))).when(tankRepository).findAll();
    // actual method call
    verify(someOtherMock, times(2)).someMethod(); 

This fails. someMethod is still only called once (I expected twice, once for each item in the list). Am I mixing doReturn and when wrong?

2reactions
szpakcommented, Nov 23, 2016

You can use:

Mockito.doAnswer(...).when(instance).foo();

as a workaround. Method foo() is executed on the proxy, so the original stubbing shouldn’t be called on the second stubbing. This syntax in general should be rather used for spies and void methods as it doesn’t provide compile time type checking.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Mockito re-stub method already stubbed with thenthrow
In new Mockito versions you can use stubbing consecutive calls to throw exception on first can and returning a value on a second...
Read more >
Repeated stubbings with Mockito - dm3
You can't override stubbing of Mockito mocks if you've already stubbed them with #willThrow / #thenThrow , because stubbed invocations will ...
Read more >
Mockito gotcha: Beware of method invocation when stubbing
We stub the same method again, inadvertently invoking the method and triggering the first stubbing with a null argument. Mystery solved, Hurrah!
Read more >
Stubs - Sinon.JS
As spies, stubs can be either anonymous, or wrap existing functions. When wrapping an existing function with a stub, the original function is...
Read more >
Mockito (Mockito API) - Javadoc.io
Original version of Mockito did not have this feature to promote simple mocking ... It is the default answer so it will be...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found