So I started writing tests for our Java-Spring-project.
What I use is JUnit and Mockito. It's said, that when I use the when()...thenReturn() option I can mock services, without simulating them or so. So what I want to do is, to set:
when(classIwantToTest.object.get().methodWhichReturnsAList(input))thenReturn(ListcreatedInsideTheTestClass)
But no matter which when-clause I do, I always get a NullpointerException, which of course makes sense, because input is null.
Also when I try to mock another method from an object:
when(object.method()).thenReturn(true)
There I also get a Nullpointer, because the method needs a variable, which isn't set.
But I want to use when()..thenReturn() to get around creating this variable and so on. I just want to make sure, that if any class calls this method, then no matter what, just return true or the list above.
Is it a basically misunderstanding from my side, or is there something else wrong?
Code:
public class classIWantToTest implements classIWantToTestFacade{
#Autowired
private SomeService myService;
#Override
public Optional<OutputData> getInformations(final InputData inputData) {
final Optional<OutputData> data = myService.getListWithData(inputData);
if (data.isPresent()) {
final List<ItemData> allData = data.get().getItemDatas();
//do something with the data and allData
return data;
}
return Optional.absent();
}
}
And here is my test class:
public class Test {
private InputData inputdata;
private ClassUnderTest classUnderTest;
final List<ItemData> allData = new ArrayList<ItemData>();
#Mock
private DeliveryItemData item1;
#Mock
private DeliveryItemData item2;
#Mock
private SomeService myService;
#Before
public void setUp() throws Exception {
classUnderTest = new ClassUnderTest();
myService = mock(myService.class);
classUnderTest.setService(myService);
item1 = mock(DeliveryItemData.class);
item2 = mock(DeliveryItemData.class);
}
#Test
public void test_sort() {
createData();
when(myService.getListWithData(inputdata).get().getItemDatas());
when(item1.hasSomething()).thenReturn(true);
when(item2.hasSomething()).thenReturn(false);
}
public void createData() {
item1.setSomeValue("val");
item2.setSomeOtherValue("test");
item2.setSomeValue("val");
item2.setSomeOtherValue("value");
allData.add(item1);
allData.add(item2);
}
I had this issue and my problem was that I was calling my method with any() instead of anyInt(). So I had:
doAnswer(...).with(myMockObject).thisFuncTakesAnInt(any())
and I had to change it to:
doAnswer(...).with(myMockObject).thisFuncTakesAnInt(anyInt())
I have no idea why that produced a NullPointerException. Maybe this will help the next poor soul.
The default return value of methods you haven't stubbed yet is false for boolean methods, an empty collection or map for methods returning collections or maps and null otherwise.
This also applies to method calls within when(...). In you're example when(myService.getListWithData(inputData).get()) will cause a NullPointerException because myService.getListWithData(inputData) is null - it has not been stubbed before.
One option is create mocks for all intermediate return values and stub them before use. For example:
ListWithData listWithData = mock(ListWithData.class);
when(listWithData.get()).thenReturn(item1);
when(myService.getListWithData()).thenReturn(listWithData);
Or alternatively, you can specify a different default answer when creating a mock, to make methods return a new mock instead of null: RETURNS_DEEP_STUBS
SomeService myService = mock(SomeService.class, Mockito.RETURNS_DEEP_STUBS);
when(myService.getListWithData().get()).thenReturn(item1);
You should read the Javadoc of Mockito.RETURNS_DEEP_STUBS which explains this in more detail and also has some warnings about its usage.
I hope this helps. Just note that your example code seems to have more issues, such as missing assert or verify statements and calling setters on mocks (which does not have any effect).
I had the same problem and my issue was simply that I had not annotated the class properly using #RunWith. In your example, make sure that you have:
#RunWith(MockitoJUnitRunner.class)
public class Test {
...
Once I did that, the NullPointerExceptions disappeared.
For future readers, another cause for NPE when using mocks is forgetting to initialize the mocks like so:
#Mock
SomeMock someMock;
#InjectMocks
SomeService someService;
#Before
public void setup(){
MockitoAnnotations.initMocks(this); //without this you will get NPE
}
#Test
public void someTest(){
Mockito.when(someMock.someMethod()).thenReturn("some result");
// ...
}
Also make sure you are using JUnit for all annotations.
I once accidently created a test with #Test from testNG so the #Before didn't work with it (in testNG the annotation is #BeforeTest)
For me the reason I was getting NPE is that I was using Mockito.any() when mocking primitives. I found that by switching to using the correct variant from mockito gets rid of the errors.
For example, to mock a function that takes a primitive long as parameter, instead of using any(), you should be more specific and replace that with any(Long.class) or Mockito.anyLong().
Hope that helps someone.
As this is the closest I found to the issue I had, it's the first result that comes up and I didn't find an appropriate answer, I'll post the solution here for any future poor souls:
any() doesn't work where mocked class method uses a primitive parameter.
public Boolean getResult(String identifier, boolean switch)
The above will produce the same exact issue as OP.
Solution, just wrap it:
public Boolean getResult(String identifier, Boolean switch)
The latter solves the NPE.
keep in mind if you choose this approach, now you might want to include a nullcheck for Boolean in production code (credit: brought up by Ridcully)
Make sure you initialize your mocks.
JUnit4 use #Before
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
JUnit5 use #BeforeEach
#BeforeEach
public void setup() {
MockitoAnnotations.initMocks(this);
}
For JUnit5 check, you are using proper imports also.
import org.junit.runner.RunWith
import org.mockito.junit.MockitoJUnitRunner;
#RunWith(MockitoJUnitRunner.class)
Corner case:
If you're using Scala and you try to create an any matcher on a value class, you'll get an unhelpful NPE.
So given case class ValueClass(value: Int) extends AnyVal, what you want to do is ValueClass(anyInt) instead of any[ValueClass]
when(mock.someMethod(ValueClass(anyInt))).thenAnswer {
...
val v = ValueClass(invocation.getArguments()(0).asInstanceOf[Int])
...
}
This other SO question is more specifically about that, but you'd miss it when you don't know the issue is with value classes.
For JUnit 5 the test class has to be annotated with:
#ExtendWith(MockitoExtension.class)
imports:
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
My issue was fixed with this addition.
you need to initialize MockitoAnnotations.initMocks(this) method has to called to initialize annotated fields.
#Before public void initMocks() {
MockitoAnnotations.initMocks(this);
}
for more details see Doc
Check that the method signature is not declared as final
This one catches out a lot of people who work on codebases which are subjected to Checkstyle and have internalised the need to mark members as final.
i.e. in the OP's example:
object.method()
Make sure that method() is not declared as final:
public final Object method() {
}
Mockito cannot mock a final method and this will come up as a wrapped NPE:
Suppressed: org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Buried deep in the error message is the following:
Also, this error might show up because you use argument matchers with methods that cannot be mocked.
Following methods *cannot* be stubbed/verified: final/private/equals()/hashCode().
Mocking methods declared on non-public parent classes is not supported.
None of the above answers helped me. I was struggling to understand why code works in Java but not in Kotlin.
Then I figured it out from this thread.
You have to make class and member functions open, otherwise NPE was being thrown.
After making function open tests started to pass.
You might as well consider using compiler's "all-open" plugin:
Kotlin has classes and their members final by default, which makes it inconvenient to use frameworks and libraries such as Spring AOP that require classes to be open. The all-open compiler plugin adapts Kotlin to the requirements of those frameworks and makes classes annotated with a specific annotation and their members open without the explicit open keyword.
For me, it was because I was stubbing the mock in the #BeforeAll method.
MockitoExtension does not have a callback for #BeforeAll.
public class MockitoExtension implements BeforeEachCallback, AfterEachCallback, ParameterResolver
I moved the stubbing inside the test method it worked!!
In my case, it was the wrong import for when().
I used import static reactor.core.publisher.Mono.when by accident.
In my case, Intellij created Test with org.junit.jupiter.api.Test (Junit5) instead of import org.junit.Test of (Junit4) which caused all beans to be null apparently.
also, make sure the class and test method is public
In my case, my Mockito annotation didn't match the JUnit Version.
When using #ExtendWith(MockitoExtension.class) make sure you're using JUnit 5: import org.junit.jupiter.api.Test;
When using #RunWith(MockitoJUnitRunner.class) make sure you're using JUnit 4: import org.junit.Test;
In my case, I missed add first
PowerMockito.spy(ClassWhichNeedToBeStaticMocked.class);
so this can be helpful to somebody who see such error
java.lang.NullPointerException
at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.addAnswersForStubbing(PowerMockitoStubberImpl.java:67)
at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:42)
at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:112)
#RunWith(MockitoJUnitRunner.class) //(OR) PowerMockRunner.class
#PrepareForTest({UpdateUtil.class,Log.class,SharedPreferences.class,SharedPreferences.Editor.class})
public class InstallationTest extends TestCase{
#Mock
Context mockContext;
#Mock
SharedPreferences mSharedPreferences;
#Mock
SharedPreferences.Editor mSharedPreferenceEdtor;
#Before
public void setUp() throws Exception
{
// mockContext = Mockito.mock(Context.class);
// mSharedPreferences = Mockito.mock(SharedPreferences.class);
// mSharedPreferenceEdtor = Mockito.mock(SharedPreferences.Editor.class);
when(mockContext.getSharedPreferences(Mockito.anyString(),Mockito.anyInt())).thenReturn(mSharedPreferences);
when(mSharedPreferences.edit()).thenReturn(mSharedPreferenceEdtor);
when(mSharedPreferenceEdtor.remove(Mockito.anyString())).thenReturn(mSharedPreferenceEdtor);
when(mSharedPreferenceEdtor.putString(Mockito.anyString(),Mockito.anyString())).thenReturn(mSharedPreferenceEdtor);
}
#Test
public void deletePreferencesTest() throws Exception {
}
}
All the above commented codes are not required
{ mockContext = Mockito.mock(Context.class); },
if you use #Mock Annotation to Context mockContext;
#Mock
Context mockContext;
But it will work if you use #RunWith(MockitoJUnitRunner.class) only. As per Mockito you can create mock object by either using #Mock or Mockito.mock(Context.class); ,
I got NullpointerException because of using #RunWith(PowerMockRunner.class), instead of that I changed to #RunWith(MockitoJUnitRunner.class) it works fine
Well in my case it was because of wrong annotation usage. I was using junit 4 for testing and used #BeforeEach instead of #Before while initializing.
Changed it to #Before and it works like charm.
This is where google took me when I had the same NullPointerException with Junit 5, but was correctly using #ExtendWith(MockitoExtension.class) in my maven project.
Turns out I hadn't included the maven-surefire-plugin in my pom.xml and that meant the #ExtendWith wasn't actually doing anything!
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.1</version>
</plugin>
...
I was using wrong annotation/import of Mock, so my object was not getting formed.
I was using org.evosuite.shaded.org.mockito.Mock and I switched back to org.mockito.Mock. Then as if by magic, it started working for me.
Ed Webb's answer helped in my case. And instead, you can also try add
#Rule public Mocks mocks = new Mocks(this);
if you #RunWith(JUnit4.class).
None of these answers worked for me. This answer doesn't solve OP's issue but since this post is the only one that shows up on googling this issue, I'm sharing my answer here.
I came across this issue while writing unit tests for Android. The issue was that the activity that I was testing extended AppCompatActivity instead of Activity. To fix this, I was able to just replace AppCompatActivity with Activity since I didn't really need it. This might not be a viable solution for everyone, but hopefully knowing the root cause will help someone.
When using JUnit 5 or above. You have to inject the class annotated with #Mock
in an #BeforeEach setup.
In my case it was due to wrong import of the #Test annotation
Make sure you are using the following import
import org.junit.jupiter.api.Test;
Annotate the test class with: #ExtendWith(MockitoExtension.class).
In my case a tested method called another method as a parameter:
Mockito.`when`(repository.getItems(prefs.getUser().id)).thenReturn(listOf())`
While repository is mocked, prefs.getUser().id) will throw NPE. So, first we should mock a parameter, for instance,
Mockito.`when`(prefs.getUser()).thenReturn(User(id = 1, name = "user"))`
Also we should mock prefs. I didn't check it and changed a library, sorry.
I was trying to mock a "final" method, which apparently was the problem.
The right way to handle this would be to use an interface and mock that interface however I couldn't control the library where the "final" method was.
Mockito 2 can handle mocking final method. Add a text file to the project's src/test/resources/mockito-extensions directory named org.mockito.plugins.MockMaker and add a single line of text:
mock-maker-inline
After that, mocking the final method should work just fine.
Check which version of Junit you are using. In the Maven/Gradle build tool, if you set to use testRuntimeOnly 'junit5',then it might not take #RunWith since it is not available and it is replaced with #ExtendWith in Junit5.
This doesnt answer the OP's original query, but its here to try help others with Mockito null pointer exceptions (NPE).
My NPE was happening as I did not explicitly set the class under tests' dependencies to be the classes I had mocked. So the class under test was unable to find its required dependencies, creating the NPE. I tend to not mock the class under test (i.e. use new keyword), to ensure im getting my native class behaviour for testing.
Im still using Junit 4 for reasons outside my control. Worked example;
ClassUnderTest
public class ClassUnderTest {
private DependantClassOne dependantClassOne;
private DependantClassTwo dependantClassTwo;
// remaining class, including setters
}
Test Class
#RunWith(MockitoJUnitRunner.class)
public class Test {
private ClassUnderTest classUnderTest;
private DependantClassOne dependantClassOne;
private DependantClassTwo dependantClassTwo;
#Before
public void setup() {
dependantClassOne = mock(DependantClassOne.class);
dependantClassTwo = mock(DependantClassTwo.class);
classUnderTest = new ClassUnderTest();
classUnderTest.setDependantClassOne(dependantClassOne); //added to prevent NPE
classUnderTest.setDependantClassTwo(dependantClassTwo); //added to prevent NPE
}
// tests
}
Related
My Code is as below,
#RunWith(MockitoJUnitRunner.class)
public class MyClass {
private static final String code ="Test";
#Mock
private MyClassDAO dao;
#InjectMocks
private MyClassService Service = new MyClassServiceImpl();
#Test
public void testDoSearch() throws Exception {
final String METHOD_NAME = logger.getName().concat(".testDoSearchEcRcfInspections()");
CriteriaDTO dto = new CriteriaDTO();
dto.setCode(code);
inspectionService.searchEcRcfInspections(dto);
List<SearchCriteriaDTO> summaryList = new ArrayList<SearchCriteriaDTO>();
inspectionsSummaryList.add(dto);
when(dao.doSearch(dto)).thenReturn(inspectionsSummaryList);//got error in this line
verify(dao).doSearchInspections(dto);
}
}
I am getting below exception
org.mockito.exceptions.misusing.UnnecessaryStubbingException:
Unnecessary stubbings detected in test class: Test
Clean & maintainable test code requires zero unnecessary code.
Following stubbings are unnecessary (click to navigate to relevant line of code):
1. -> at service.Test.testDoSearch(Test.java:72)
Please remove unnecessary stubbings or use 'silent' option. More info: javadoc for UnnecessaryStubbingException class.
at org.mockito.internal.exceptions.Reporter.formatUnncessaryStubbingException(Reporter.java:838)
at org.mockito.internal.junit.UnnecessaryStubbingsReporter.validateUnusedStubs(UnnecessaryStubbingsReporter.java:34)
at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:49)
at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:103)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Please help me how to resolve
At first you should check your test logic. Usually there are 3 cases. First, you are mocking the wrong method (you made a typo or someone changed tested code so that mocked method is no longer used). Second, your test is failing before this method is called. Third, your logic falls in wrong if/switch branch somewhere in the code so that mocked method is not called.
If this is the first case you always want to change the mocked method for the one used in the code. With the second and the third it depends. Usually you should just delete this mock if it has no use. But sometimes there are certain cases in parametrized tests, which should take this different path or fail earlier. Then you can split this test into two or more separate ones but that's not always good looking. 3 test methods with possibly 3 arguments providers can make your test look unreadable. In that case for JUnit 4 you silent this exception with either
#RunWith(MockitoJUnitRunner.Silent.class)
annotation or if you are using rule approach
#Rule
public MockitoRule rule = MockitoJUnit.rule().strictness(Strictness.LENIENT);
or (the same behaviour)
#Rule
public MockitoRule rule = MockitoJUnit.rule().silent();
For JUnit 5 tests you can silence this exception using this annotation provided in mockito-junit-jupiter package:
#ExtendWith(MockitoExtension.class)
#MockitoSettings(strictness = Strictness.LENIENT)
class JUnit5MockitoTest {
}
Replace #RunWith(MockitoJUnitRunner.class) with #RunWith(MockitoJUnitRunner.Silent.class).
For me neither the #Rule nor the #RunWith(MockitoJUnitRunner.Silent.class) suggestions worked. It was a legacy project where we upgraded to mockito-core 2.23.0.
We could get rid of the UnnecessaryStubbingException by using:
Mockito.lenient().when(mockedService.getUserById(any())).thenReturn(new User());
instead of:
when(mockedService.getUserById(any())).thenReturn(new User());
Needless to say that you should rather look at the test code, but we needed to get the stuff compiled and the tests running first of all ;)
Silent is not a solution. You need fix your mock in your test. See official documentation here.
Unnecessary stubs are stubbed method calls that were never realized during test execution (see also MockitoHint), example:
//code under test:
...
String result = translator.translate("one")
...
//test:
...
when(translator.translate("one")).thenReturn("jeden"); // <- stubbing realized during code execution
when(translator.translate("two")).thenReturn("dwa"); // <- stubbing never realized
...
Notice that one of the stubbed methods were never realized in the code under test, during test execution. The stray stubbing might be an oversight of the developer, the artifact of copy-paste or the effect not understanding the test/code. Either way, the developer ends up with unnecessary test code. In order to keep the codebase clean & maintainable it is necessary to remove unnecessary code. Otherwise tests are harder to read and reason about.
To find out more about detecting unused stubbings see MockitoHint.
when(dao.doSearch(dto)).thenReturn(inspectionsSummaryList);//got error in this line
verify(dao).doSearchInspections(dto);
The when here configures your mock to do something. However, you donot use this mock in any way anymore after this line (apart from doing a verify). Mockito warns you that the when line therefore is pointless. Perhaps you made a logic error?
Replace
#RunWith(MockitoJUnitRunner.class)
with
#RunWith(MockitoJUnitRunner.Silent.class)
or remove #RunWith(MockitoJUnitRunner.class)
or just comment out the unwanted mocking calls (shown as unauthorised stubbing).
This was already pointed out in this comment, but I think that's too easy to overlook: You may run into an UnnecessaryStubbingException if you simply convert a JUnit 4 test class to a JUnit 5 test class by replacing an existing #Before with #BeforeEach, and if you perform some stubbing in that setup method that is not realized by at least one of the test cases.
This Mockito thread has more information on that, basically there is a subtle difference in the test execution between #Before and #BeforeEach. With #Before, it was sufficient if any test case realized the stubbings, with #BeforeEach, all cases would have to.
If you don't want to break up the setup of #BeforeEach into many small bits (as the comment cited above rightly points out), there's another option still instead of activating the lenient mode for the whole test class: you can merely make those stubbings in the #BeforeEach method lenient individually using lenient().
As others pointed out it is usually the simplest to remove the line that is unnecessarily stubbing a method call.
In my case it was in a #BeforeEach and it was relevant most of the time. In the only test where that method was not used I reset the mock, e.g.:
myMock.reset()
Hope this helps others with the same problem.
(Note that if there are multiple mocked calls on the same mock this could be inconvenient as well since you'll have to mock all the other methods except the one that isn't called.)
Looking at a part of your stack trace it looks like you are stubbing the dao.doSearch() elsewhere. More like repeatedly creating the stubs of the same method.
Following stubbings are unnecessary (click to navigate to relevant line of code):
1. -> at service.Test.testDoSearch(Test.java:72)
Please remove unnecessary stubbings or use 'silent' option. More info: javadoc for UnnecessaryStubbingException class.
Consider the below Test Class for example:
#RunWith(MockitoJUnitRunner.class)
public class SomeTest {
#Mock
Service1 svc1Mock1;
#Mock
Service2 svc2Mock2;
#InjectMock
TestClass class;
//Assume you have many dependencies and you want to set up all the stubs
//in one place assuming that all your tests need these stubs.
//I know that any initialization code for the test can/should be in a
//#Before method. Lets assume there is another method just to create
//your stubs.
public void setUpRequiredStubs() {
when(svc1Mock1.someMethod(any(), any())).thenReturn(something));
when(svc2Mock2.someOtherMethod(any())).thenReturn(somethingElse);
}
#Test
public void methodUnderTest_StateUnderTest_ExpectedBehavior() {
// You forget that you defined the stub for svcMock1.someMethod or
//thought you could redefine it. Well you cannot. That's going to be
//a problem and would throw your UnnecessaryStubbingException.
when(svc1Mock1.someMethod(any(),any())).thenReturn(anyThing);//ERROR!
setUpRequiredStubs();
}
}
I would rather considering refactoring your tests to stub where necessary.
Well, In my case Mockito error was telling me to call the actual method after the when or whenever stub. Since we were not invoking the conditions that we just mocked, Mockito was reporting that as unnecessary stubs or code.
Here is what it was like when the error was coming :
#Test
fun `should return error when item list is empty for getStockAvailability`() {
doAnswer(
Answer<Void> { invocation ->
val callback =
invocation.arguments[1] as GetStockApiCallback<StockResultViewState.Idle, StockResultViewState.Error>
callback.onApiCallError(stockResultViewStateError)
null
}
).whenever(stockViewModelTest)
.getStockAvailability(listOf(), getStocksApiCallBack)
}
then I just called the actual method mentioned in when statement to mock the method.
changes done is as below
stockViewModelTest.getStockAvailability(listOf(), getStocksApiCallBack)
#Test
fun `should return error when item list is empty for getStockAvailability`() {
doAnswer(
Answer<Void> { invocation ->
val callback =
invocation.arguments[1] as GetStockApiCallback<StockResultViewState.Idle, StockResultViewState.Error>
callback.onApiCallError(stockResultViewStateError)
null
}
).whenever(stockViewModelTest)
.getStockAvailability(listOf(), getStocksApiCallBack)
//called the actual method here
stockViewModelTest.getStockAvailability(listOf(), getStocksApiCallBack)
}
it's working now.
If you're using this style instead:
#Rule
public MockitoRule rule = MockitoJUnit.rule().strictness(Strictness.STRICT_STUBS);
replace it with:
#Rule
public MockitoRule rule = MockitoJUnit.rule().silent();
I had UnnecessaryStubbingException when I tried to use the when methods on a Spy object.
Mockito.lenient() silenced the exception but the test results were not correct.
In case of Spy objects, one has to call the methods directly.
#ExtendWith(MockitoExtension.class)
#RunWith(JUnitPlatform.class)
class ArithmTest {
#Spy
private Arithm arithm;
#Test
void testAddition() {
int res = arithm.add(2, 5);
// doReturn(7).when(arithm).add(2, 5);
assertEquals(res, 7);
}
}
In case of a large project, it's difficult to fix each of these exceptions. At the same time, using Silent is not advised. I have written a script to remove all the unnecessary stubbings given a list of them.
https://gist.github.com/cueo/da1ca49e92679ac49f808c7ef594e75b
We just need to copy-paste the mvn output and write the list of these exceptions using regex and let the script take care of the rest.
If you use any() when mocking, you have to relpace #RunWith(MockitoJUnitRunner.class) with
#RunWith(MockitoJUnitRunner.Silent.class).
I am attempting to use Junit, mockito and PowerMock to create a unit test
My problem is that one of the classes which i am attempting to mock is returning a null object
This is my code
#RunWith(PowerMockRunner.class)
#PrepareForTest(ClientBuilder.class)
public class SolrPopulateApplicationTest {
#Mock
ClientConfig clientConfig;
#Mock
Client client;
#Mock
Response response;
#Mock
JerseyClient jerseyClient;
#Mock (answer = Answers.RETURNS_DEEP_STUBS)
JerseyWebTarget jerseyWebTarget;
#InjectMocks
#Autowired
SolrPopulateApplication solrPopulateApplication;
#Test
public void indexTest(){
PowerMockito.mockStatic(ClientBuilder.class);
ClientBuilder cli = Mockito.mock(ClientBuilder.class);
when(ClientBuilder.newClient(Matchers.any())).thenReturn(client);
when(jerseyClient.target(Matchers.anyString())).thenReturn(jerseyWebTarget);
when(jerseyWebTarget.path(Matchers.anyString())
.queryParam(Matchers.anyString(),Matchers.anyString())
.request(Matchers.anyString())
.header(Matchers.anyString(),Matchers.anyString())
.post(Matchers.any())).thenReturn(response);
boolean var = solrPopulateApplication.index("test","test");
}
}
When a debug breakpoint is placed after all the mocks should have been setup i get the following
client = {Client$$EnhancerByMockitoWithCGLIB$$7f4c6946#1705} "client"
response = {Response$$EnhancerByMockitoWithCGLIB$$b85fdf42#1704} "response"
jerseyWebTarget = {JerseyWebTarget$$EnhancerByMockitoWithCGLIB$$7d7091b9#1703} "null"
solrPopulateApplication = {SolrPopulateApplication#1702}
jerseyClient = {JerseyClient$$EnhancerByMockitoWithCGLIB$$6437ba91#1701} "jerseyClient"
cli = {ClientBuilder$$EnhancerByMockitoWithCGLIB$$20196b6d#1700} "Mock for ClientBuilder, hashCode: 2080643905"
this = {SolrPopulateApplicationTest#1695}
as you can see the jerseyWebClient is a NULL and this is causing a nullpointerexception when i try to run the test.
I have tried removing (answer = Answers.RETURNS_DEEP_STUBS) from the #mock statement and this makes no difference.
The method being tested actually calls a interface which implements the JerseyWebTarget class. I have made sure I am trying to mock the right class by putting a debugger in the JerseyWebTarget class to make sure its stopping on the method which is being called via the interface.
can anyone tell me why this is happening and how to fix it.
Assuming that you are using the Mockito #Mock annotation...
To use the Mockito #Mock annotation, you have to execute a particular line of code before each test. You can do this in a set up method:
#Before
public void init() {
MockitoAnnotations.initMocks(this);
}
You also have to #RunWith(MockitoJUnitRunner.class) but as you are using the PowerMockRunner then this may not be necessary.
I would recommend that you avoid using PowerMock if at all possible, or at least get your mock working with Mockito before moving on to write the test with PowerMock. I quote the following from the PowerMock wiki:
Please note that PowerMock is mainly intended for people with expert knowledge in unit testing. Putting it in the hands of junior developers may cause more harm than good.
Unless there is a very specific reason why PowerMock is required here, avoid it. For example, you could pass the JerseyWebTarget into the constructor of your SolrPopulateApplication instead of making a direct call to ClientBuilder inside the class you are testing.
Furthermore, it's possible that PowerMock and Mockito will not always play nice together. For example, see this bug.
I'm using Mockito 1.9.0. I want mock the behaviour for a single method of a class in a JUnit test, so I have
final MyClass myClassSpy = Mockito.spy(myInstance);
Mockito.when(myClassSpy.method1()).thenReturn(myResults);
The problem is, in the second line, myClassSpy.method1() is actually getting called, resulting in an exception. The only reason I'm using mocks is so that later, whenever myClassSpy.method1() is called, the real method won't be called and the myResults object will be returned.
MyClass is an interface and myInstance is an implementation of that, if that matters.
What do I need to do to correct this spying behaviour?
Let me quote the official documentation:
Important gotcha on spying real objects!
Sometimes it's impossible to use when(Object) for stubbing spies. Example:
List list = new LinkedList();
List spy = spy(list);
// Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
when(spy.get(0)).thenReturn("foo");
// You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
In your case it goes something like:
doReturn(resultsIWant).when(myClassSpy).method1();
In my case, using Mockito 2.0, I had to change all the any() parameters to nullable() in order to stub the real call.
My case was different from the accepted answer. I was trying to mock a package-private method for an instance that did not live in that package
package common;
public class AnimalĀ {
void packageProtected();
}
package instances;
class Dog extends Animal { }
and the test classes
package common;
public abstract class AnimalTest<T extends Animal> {
#Before
setup(){
doNothing().when(getInstance()).packageProtected();
}
abstract T getInstance();
}
package instances;
class DogTest extends AnimalTest<Dog> {
Dog getInstance(){
return spy(new Dog());
}
#Test
public void myTest(){}
}
The compilation is correct, but when it tries to setup the test, it invokes the real method instead.
Declaring the method protected or public fixes the issue, tho it's not a clean solution.
The answer by Tomasz Nurkiewicz appears not to tell the whole story!
NB Mockito version: 1.10.19.
I am very much a Mockito newb, so can't explain the following behaviour: if there's an expert out there who can improve this answer, please feel free.
The method in question here, getContentStringValue, is NOT final and NOT static.
This line does call the original method getContentStringValue:
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), isA( ScoreDoc.class ));
This line does not call the original method getContentStringValue:
doReturn( "dummy" ).when( im ).getContentStringValue( anyInt(), any( ScoreDoc.class ));
For reasons which I can't answer, using isA() causes the intended (?) "do not call method" behaviour of doReturn to fail.
Let's look at the method signatures involved here: they are both static methods of Matchers. Both are said by the Javadoc to return null, which is a little difficult to get your head around in itself. Presumably the Class object passed as the parameter is examined but the result either never calculated or discarded. Given that null can stand for any class and that you are hoping for the mocked method not to be called, couldn't the signatures of isA( ... ) and any( ... ) just return null rather than a generic parameter* <T>?
Anyway:
public static <T> T isA(java.lang.Class<T> clazz)
public static <T> T any(java.lang.Class<T> clazz)
The API documentation does not give any clue about this. It also seems to say the need for such "do not call method" behaviour is "very rare". Personally I use this technique all the time: typically I find that mocking involves a few lines which "set the scene" ... followed by calling a method which then "plays out" the scene in the mock context which you have staged... and while you are setting up the scenery and the props the last thing you want is for the actors to enter stage left and start acting their hearts out...
But this is way beyond my pay grade... I invite explanations from any passing Mockito high priests...
* is "generic parameter" the right term?
One more possible scenario which may causing issues with spies is when you're testing spring beans (with spring test framework) or some other framework that is proxing your objects during test.
Example
#Autowired
private MonitoringDocumentsRepository repository
void test(){
repository = Mockito.spy(repository)
Mockito.doReturn(docs1, docs2)
.when(repository).findMonitoringDocuments(Mockito.nullable(MonitoringDocumentSearchRequest.class));
}
In above code both Spring and Mockito will try to proxy your MonitoringDocumentsRepository object, but Spring will be first, which will cause real call of findMonitoringDocuments method. If we debug our code just after putting a spy on repository object it will look like this inside debugger:
repository = MonitoringDocumentsRepository$$EnhancerBySpringCGLIB$$MockitoMock$
#SpyBean to the rescue
If instead #Autowired annotation we use #SpyBean annotation, we will solve above problem, the SpyBean annotation will also inject repository object but it will be firstly proxied by Mockito and will look like this inside debugger
repository = MonitoringDocumentsRepository$$MockitoMock$$EnhancerBySpringCGLIB$
and here is the code:
#SpyBean
private MonitoringDocumentsRepository repository
void test(){
Mockito.doReturn(docs1, docs2)
.when(repository).findMonitoringDocuments(Mockito.nullable(MonitoringDocumentSearchRequest.class));
}
Important gotcha on spying real objects
When stubbing a method using spies , please use doReturn() family of methods.
when(Object) would result in calling the actual method that can throw exceptions.
List spy = spy(new LinkedList());
//Incorrect , spy.get() will throw IndexOutOfBoundsException
when(spy.get(0)).thenReturn("foo");
//You have to use doReturn() for stubbing
doReturn("foo").when(spy).get(0);
I've found yet another reason for spy to call the original method.
Someone had the idea to mock a final class, and found about MockMaker:
As this works differently to our current mechanism and this one has different limitations and as we want to gather experience and user feedback, this feature had to be explicitly activated to be available ; it can be done via the mockito extension mechanism by creating the file src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker containing a single line: mock-maker-inline
Source: https://github.com/mockito/mockito/wiki/What%27s-new-in-Mockito-2#mock-the-unmockable-opt-in-mocking-of-final-classesmethods
After I merged and brought that file to my machine, my tests failed.
I just had to remove the line (or the file), and spy() worked.
One way to make sure a method from a class is not called is to override the method with a dummy.
WebFormCreatorActivity activity = spy(new WebFormCreatorActivity(clientFactory) {//spy(new WebFormCreatorActivity(clientFactory));
#Override
public void select(TreeItem i) {
log.debug("SELECT");
};
});
As mentioned in some of the comments, my method was "static" (though being called on by an instance of the class)
public class A {
static void myMethod() {...}
}
A instance = spy(new A());
verify(instance).myMethod(); // still calls the original method because it's static
Work around was make an instance method or upgrade Mockito to a newer version with some config: https://stackoverflow.com/a/62860455/32453
Bit late to the party but above solutions did not work for me , so sharing my 0.02$
Mokcito version: 1.10.19
MyClass.java
private int handleAction(List<String> argList, String action)
Test.java
MyClass spy = PowerMockito.spy(new MyClass());
Following did NOT work for me (actual method was being called):
1.
doReturn(0).when(spy , "handleAction", ListUtils.EMPTY_LIST, new String());
2.
doReturn(0).when(spy , "handleAction", any(), anyString());
3.
doReturn(0).when(spy , "handleAction", null, null);
Following WORKED:
doReturn(0).when(spy , "handleAction", any(List.class), anyString());
I have gone through some of the blogs in order to understand the basics of how Mockito annotations work.
However I am facing a doubt as to when does one go for manually instantiating the field annotated with #InjectMocks i.e
#InjectMocks
A a = new A();
And when does one rely on MockitoAnnotations.initMocks() functionality to do the same :
#InjectMocks
A a;
Does this depend on the JunitTestRunner that we employ to run the test cases or is it dependent on the Mockito framework version?
It depends if you are using (declaring) the runner or not.
If you use the runner, you don't need to call MockitoAnnotations.initMocks() yourself - the runner calls it for you.
Usually we go for the runner. When you want to use other runners, though (like Spring's), you can call .initMocks() yourself.
Just to be clear, the MockitoAnnotations.initMocks(this) will:
Instantiate the field annotated with #InjectMocks
Create a mock version of every field annotated with #Mock
Inject the #Mocks in the #InjectMocks variable's fields (or call its constructors or use its setters - it depends on what kind of Dependency Injection you use)
Mockito runner, initMocks and rule code samples
The three code samples below should be equivalent.
With runner:
This first snippet uses the runner, making the call to initMocks() unnecessary.
#RunWith(MockitoJUnitRunner.class)
public class MyClassTest {
#Mock private MyDependency myDependency;
#InjectMocks private MyClass myClass;
#Test
public void myClass_should_get_stuff_from_dependency() {
when(myDependency.getStuff()).thenReturn("stuff!");
assertThat(myClass.getDependencyStuff(), is("stuff!"));
}
}
Without runner + with manual call to .initMocks():
This other does not use the runner, thus the need for the setUp() method calling our initMocks() friend.
// notice there is no runner
public class MyClassTest {
#Mock private MyDependency myDependency;
#InjectMocks private MyClass myClass;
// but now you have to call initMocks() yourself
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
#Test
public void myClass_should_get_stuff_from_dependency() {
when(myDependency.getStuff()).thenReturn("stuff!");
assertThat(myClass.getDependencyStuff(), is("stuff!"));
}
}
Without runner or manual call, using #Rule:
Finally, as pointed out in the comments (thanks #StefanBirkner), since version 1.10.17, there is also the possibility of using a JUnit #Rule called MockitoRule:
public class MyClassTest {
#Rule
public MockitoRule rule = MockitoJUnit.rule();
#Mock private MyDependency myDependency;
#InjectMocks private MyClass myClass;
#Test
public void myClass_should_get_stuff_from_dependency() {
when(myDependency.getStuff()).thenReturn("stuff!");
assertThat(myClass.getDependencyStuff(), is("stuff!"));
}
}
In general, the decision to instantiate an object which is annotated with #InjectMocks or not is a code style choice. In the majority of cases there will be no difference as Mockito is designed to handle both situations.
However, there is some differences which I have outlined below.
#InjectMocks decouples a test from changes to the constructor.
In the same way using a Dependency Injection framework decouples your production code from changes to the constructor. Allowing Mockito to instantiate an instance of the class for you decouples your test code from changes to the constructor. This means any future changes to the class constructor can be done without causing compilation errors in the unit test.
In my opinion this is the biggest difference and the biggest advantage of #InjectMocks.
Mockito will always call the "biggest" constructor
Note: This difference is only relevant when the code you are working with does not follow best practices.
When there is multiple constructors in a class, Mocktio will call the constructor with the most parameters, the "biggest" constructor.
This only has an impact when,
A "small" constructor contains logic.
This logic is required for the class to function correctly.
The "biggest" constructor does not invoke the next "smallest" constructor.
This is considered bad practice because,
Placing logic within a constructor should be avoided whenever possible.
When there is multiple constructors within a class each constructor should first invoke the constructor before it.
Thanks for your valuable thoughts.
But still it doesn't answer the question as to why one goes for manually instantiating the field annotated with #InjectMocks when the instantiation should be handled by a call to MockitoAnnotations.initMocks().
I get the following error when trying to run the test file :
Caused by: org.mockito.exceptions.base.MockitoException: Field 'student' annotated with #InjectMocks is null.
Please make sure the instance is created before MockitoAnnotations.initMocks();
Example of correct usage:
class SomeTest {
#InjectMocks private Foo foo = new Foo();
#Before public void setUp() {
MockitoAnnotations.initMock(this);
I searched further and found out that the error is thrown if one is using an older version of Mockito framework.
http://myshittycode.com/category/testing/mockito/
I've been testing my code behavior using TestNG and JMockit for a while now and I have had no specific issue with their combination. Today I came across a situation where I needed to mock one of my internal dependencies, in the so called, type wide manner and I did not need to keep that mock around since none of the test cases dealt with it directly while they counted on the mocked version functionality. So, naturally, I put the mocking logic in my #BeforeMethod. Here is a sample:
public class SampleTest
{
#Mocked
#Cascading
private InnerDependency dependency;
#BeforeMethod
public void beforeMethod()
{
new NonStrictExpectations()
{
{
dependency.getOutputStream((String)any);
result = new Delegate<OutputStream>()
{
public OutputStream getOutputStream(String url)
{
return null;
}
};
}
};
}
#Test
public void testNormalOperation()
{
// The test whose desired behavior depends on dependency being mocked out
// ..
}
}
But, since my tests do not care about the mocked dependency explicitly, I'm not willing to declare it as a test class field, unlike what is done above. To my knowledge of JMockit The only options remaining would be:
Declare dependency as a local mock field:
new NonStrictExpectations()
{
#Cascading
private InnerDependency dependency;
{
//...
}
}
Declare dependency as an input argument for beforeMethod(), similar to what is done for normal #Test methods:
#BeforeMethod
public void beforeMethod(#Mocked #Cascading final InnerDependency dependency)
{
// ...
}
I see that JMockit 1.6+ would not like the first option and warns with WARNING: Local mock field "dependency" should be moved to the test class or converted to a parameter of the test method. Hence, to keep everyone happy, I'm ruling this option out.
But for the second option, TestNG (currently 6.8.6) throws exception when running the test saying java.lang.IllegalArgumentException: wrong number of arguments. I don't see this behavior with normal #Test cases passed with #Mocked parameters. Even playing with #Parameter and #Optional will not help (and should not have!).
So, is there any way I could make this work without declaring the unneccessary test class mock field, or am I missing something here?
Thanks
Only test methods (annotated with #Test in JUnit or TestNG) support mock parameters, so the only choice here is to declare a mock field at the test class level.
Even if not used in any test method, I think it's better than having it declared in a setup method (using #Before, #BeforeMethod, etc.). If it were to be possible, the mock would still have to apply to all tests, because of the nature of setup methods; having a mock field of the test class makes it clear what the scope of the mock is.
Dynamic partial mocking is one more technique to specify #Mocked dependencies locally. However, it has it's limitations (see comments below).