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.

Constructor Injected Class Instance Variable Loses Mocking doThrow or doReturn Doesn't work

See original GitHub issue

I have a spring boot application and am using MockitoSugar to write tests. Spring boot version: 2.0.5.RELEASE Scala version: 2.11.8 mockito-scala_2.11: 1.2.4

Injecting mock in constructor:

 val headerParamsResolverMock = mock[HeaderParamsResolver]
 val irsArgumentResolver = new IRSArgumentResolver(headerParamsResolverMock)

Test Case:

"resolverArgument" should "invoke resolve method if header parameter is not resolved" in {
val parameter = mock[Parameter]
doReturn(parameter, Nil: _*).when(methodParameterMock).getParameter
doReturn("string", Nil: _*).when(parameter).getName
doReturn(false, Nil: _*).when(headerParamsResolverMock).isResolved
doReturn("string", Nil: _*).when(headerParamsResolverMock).resolve(mock[NativeWebRequest]) // doesn't work


irsArgumentResolver.resolveArgument(methodParameterMock, mock[ModelAndViewContainer], mock[NativeWebRequest],
    mock[WebDataBinderFactory])

Mockito.verify(headerParamsResolverMock).resolve(mock[NativeWebRequest])
}

Class under test

 @Component
 public final class IRSArgumentResolver implements HandlerMethodArgumentResolver {

private HeaderParamsResolver headerParamsResolver;

public IRSArgumentResolver(HeaderParamsResolver headerParamsResolver) {
    this.headerParamsResolver = headerParamsResolver;
 }
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
                              WebDataBinderFactory binderFactory) {

    String sample = "";
    if (!headerParamsResolver.isResolved())
        sample = headerParamsResolver.resolve(webRequest);

    System.out.println(sample); // here its null 
    return webRequest.getParameter(parameter.getParameter().getName());
}

}

If I see the debugger, the headerParamsResolver isn’t shown as a mock object like other method parameters show up. Like Mock for Method Paramater OR Mock for ModelAndViewContainer etc. Moreover, only the isResolved class instance variable is set but other mock features like doThrow or doReturn doesn’t work. PFA debugger screen.

Screen Shot 2019-04-03 at 1 57 10 PM

Moreover, this test case throws exception:
Screen Shot 2019-04-03 at 2 28 23 PM

Issue Analytics

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

github_iconTop GitHub Comments

1reaction
bbonannocommented, Apr 3, 2019

@gursahibsahni There are quite a few things wrong with this, let’s separate them in 2

  1. The project you uploaded to GitHub fails because maven resolves the wrong artifacts all around, similar to this bug, I had to manually add mockito-core and bytebuddy to make it run.
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>2.25.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>net.bytebuddy</groupId>
            <artifactId>byte-buddy</artifactId>
            <version>1.9.7</version>
        </dependency>
        <dependency>
            <groupId>net.bytebuddy</groupId>
            <artifactId>byte-buddy-agent</artifactId>
            <version>1.9.7</version>
        </dependency>
  1. The test you wrote has some issues
  • The cause of the exception you posted is that you can’t create a mock while you are verifying (line 57), I guess you probably want something like
Mockito.verify(headerParamsResolverMock).resolve(any[NativeWebRequest])
  • HeaderParamsResolver is being mocked properly, the fact that it looks like the real thing in the debugger is due to how the inline mocker works
  • Line 50 should stub false (I guess this is a typo as in the code above it does that)
  • The last stubbing is never going to work as nothing is gonna be equal to a mock you create and dispose, again I guess you want
doReturn("string", Nil: _*).when(headerParamsResolverMock).resolve(any[NativeWebRequest])
  • You still use pretty much the Java Mockito everywhere, if you were to use mockito-scala, your test would look more like
  "resolverArgument" should {
    "invoke resolve method if header parameter is not resolved" in {
      val parameter = mock[Parameter]

      doReturn(parameter).when(methodParameterMock).getParameter
      doReturn("string").when(parameter).getName
      doReturn(false).when(headerParamsResolverMock).isResolved
      doReturn("string").when(headerParamsResolverMock).resolve(*)
      
      irsArgumentResolver.resolveArgument(methodParameterMock, mock[ModelAndViewContainer], mock[NativeWebRequest], mock[WebDataBinderFactory])

      verify(headerParamsResolverMock).resolve(*)
    }
  }
0reactions
gursahibsahnicommented, Apr 4, 2019

thanks for the instructions

Read more comments on GitHub >

github_iconTop Results From Across the Web

Mockito injection not working for constructor AND setter mocks ...
Constructor injection will NOT be used if the type of one or more of the parameters of the CHOSEN constructor is a primitive...
Read more >
Mockito (Mockito 4.10.0 API) - javadoc.io
Shorthand for mocks creation - @Mock annotation. Minimizes repetitive mock creation code. Makes the test class more readable. Makes the verification error ...
Read more >
Diff - platform/external/mockito - Google Git
+ * If non-mockable types are wanted, then constructor injection won't happen. ... + * Mockito doesn't mock final methods so the bottom...
Read more >
Make services unit testable using dependency injection
To tell Spring DI that you want some dependencies to be injected into a class constructor, use another annotation called @Autowired . Okay, ......
Read more >
Use Mockito to Mock Autowired Fields - DZone
I would suggest to use constructor injection instead. Dependency injection is very powerful feature of Inversion of Control containers like ...
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