Mockito Matcher parameters showing as undefined - java

I am trying to Mock a method contained in the Main class of an application. I'd like to test that when all parameters are submitted successfully, the application calls the correct method, uploadFiles. The when - thenReturn pair is shown below:
NrClient nrClient = (NrClient)Mockito.mock(NrClient.class);
Mockito.when(nrClient.uploadFiles("DF49ACBC8", anyList(), "dl")).thenReturn("");
This shows as a runtime exception: "The method anyString() is undefined for the type MainTest."
I have the imports:
import org.mockito.Mockito;
import org.mockito.Matchers;
So why would this method be undefined? Is there an issue in my implementation?
I have also tried anyString() and anyInt() with the same result.

You should be getting it as a compile-time error, not an exception (unless the actual exception is that you've got an unresolved compile-time error).
Just importing org.mockito.Matchers means you can use the name Matchers to mean org.mockito.Matchers anywhere in the class. If you want to import the methods, you need a static wildcard import:
import static org.mockito.Matchers.*;
Or specific methods:
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.anyList;
Or you could just qualify the method name in the calling code instead:
Mockito.when(nrClient.uploadFiles("DF49ACBC8", Matchers.anyList(), "dl"))
.thenReturn("");

Use the below import
import static org.mockito.ArgumentMatchers.*;
Avoid to use Matchers class because it is now deprecated in order to avoid a name clash with Hamcrest org.hamcrest.Matchers class.

Related

Powermock throws InvalidUseOfMatchersException when mocking private method

I'm new to Powermock. Yesterday I watched a video about using Powermock, I follow their code and have a demo test program below. When I run the test
package myPackage;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentMatchers;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
public class Test1{
#Test
public void testPrivateMethod() throws Exception {
DemoService mockDemoService = PowerMockito.spy(new DemoService());
PowerMockito.when(
mockDemoService,
"privateMethod",
ArgumentMatchers.any(String.class)
).then(invocation -> invocation.getArgument(0) + "_private_mock");
Assert.assertEquals(mockDemoService.dependentMethod("LoveTest"), "3000LoveTest_private_mock");
}
}
class DemoService {
private String privateMethod(String input) {
return input + "_private";
}
public String dependentMethod(String input) {
return 3000 + privateMethod(input);
}
}
It throw exception in the log below
org.mockito.exceptions.misusing.InvalidUseOfMatchersException:
Misplaced or misused argument matcher detected here:
-> at myPackage.Test1.testPrivateMethod(Test1.java:19)
You cannot use argument matchers outside of verification or stubbing.
Examples of correct usage of argument matchers:
when(mock.get(anyInt())).thenReturn(null);
doThrow(new RuntimeException()).when(mock).someVoidMethod(anyObject());
verify(mock).someMethod(contains("foo"))
This message may appear after an NullPointerException if the last matcher is returning an object
like any() but the stubbed method signature expect a primitive argument, in this case,
use primitive alternatives.
when(mock.get(any())); // bad use, will raise NPE
when(mock.get(anyInt())); // correct usage use
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.
I have some basic knowledge about Mockito, the code is somewhat similar to Mockito unit test (Mockito.spy and Mockito.when) but not work as expected. I don't know what's wrong with the code, why the exception InvalidUseOfMatchersException is thrown. Please help me, thank you.
Your code is missing #PrepareForTest. Powermock has to manipulate the byte-code of target mocking class, so you have to provide a path to it.
#RunWith(PowerMockRunner.class)
#PrepareForTest(DemoService.class)
public class Test1{
...
here ArgumentMatchers.any(String.class)
instead use ArgumentMatchers.anyString()

PowerMockito: Trying to mock System class methods or any other Final class method

I am trying to mock System class to get a constant value for currentTimeMillis().
Since I cannot use Mockito for mocking final classes I am using PowerMock, but when mocking the System.currentTimeMillis() I am geting error "Cannot resolve method when(long)".
My code looks like:
PowerMockito.mockStatic(System.class);
when(System.currentTimeMillis()).thenReturn(CURRENT_TIME_STAMP);
I have also annoted my class as:
#RunWith(PowerMockRunner.class)
#PrepareForTest(System.class)
public class DateTimeUtilsTest {
Resolved.
It should be like
PowerMockito.when(System.currentTimeMillis()).thenReturn(CURRENT_TIME_STAMP);
or import the PowerMockito statically like
import static org.powermock.api.mockito.PowerMockito.mockStatic;
import static org.powermock.api.mockito.PowerMockito.when;
Similarly, one can mock any of the System class methods or can mock any other final class.
This is why you should write tests first, then you don't write untestable code.
Your code should not access transient statics directly, but through a component you can mock.

Imported method will not work unless full class path is used

I am having trouble with a method that can be accessed using the full class path, but if I try and import it and call the method, it says that method is not defined for the current class. Here is a screenshot of the issue:
"The method equalTo(int) is undefined for the type App"
If you wish to call the method like the line 7 of your screenshot indicates, you would need to use static import:
import static org.hamcrest.Matchers.equalTo;
This will allow you to call the method as you seem to need:
equalTo(5);
import static org.hamcrest.Matchers.*;
you need to define static imports. The equalTo(T) is a static method.
Or you can access it with class name like:
Matchers.equalTo(5);
You can't access a method directly. You need to specify the class that has this method.
You should change your import to "org.harmcrest.Matchers"
And use: "Matchers.equalTo(5);"
Unless, of course, you use "import static", like the others users have shown. :)

Import for mockito

I am trying to put statement like
when(myDao.fetchTree(anyLong())).thenReturn(myTreeList);
and I have import
import static org.mockito.Mockito.when;
import static org.mockito.Matchers.anyLong;
import static org.mockito.Matchers.thenReturn; //not importing
import for thenReturn is not mapping. Is this a version issue? I am using Mockito 1.8.4.
Mockito's when returns an object of class OngoingStubbing. This class has a method thenReturn(), and that's what gets called in your example code. No additional import is needed.
when(myDao.fetchTree(anyLong())).thenReturn(myTreeList);
could be broken up as
OngoingStubbing thing = when(myDao.fetchTree(anyLong()));
thing.thenReturn(myTreeList);
You are just calling the thenReturn method of OngoingStubbing.
It should be enough if you use:
import static org.mockito.Mockito.*;
And remove the rest.
Your question: Is this a version issue?
I'd say NO, that is not a version issue.
As suggested previously, you should
create minimal test with this code in test
when(myDao.fetchTree(anyLong())).thenReturn(myTreeList);
run this code from command-line (not inside in STS or any IDE or something a like)
Q: Why run it from command-line and avoid using IDE-s etc?
A: Because sometimes code parsers and checkers and validators of your favorited IDE reports false positives about some corner-cases in code.

PowerMock not stubbing static method properly?

I'm trying to write a VERY simple test, using powermock and Robolectric. Here's my code:
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PowerMockIgnore;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.robolectric.RobolectricTestRunner;
import org.junit.Test;
import org.junit.runner.RunWith;
#RunWith(RobolectricTestRunner.class)
#PowerMockIgnore({ "org.mockito.*", "org.robolectric.*", "android.*" })
#PrepareForTest(BadStaticClass.class)
public class SomeActivityTest {
#Test
public void testSomething() {
PowerMockito.mockStatic(BadStaticClass.class);
Mockito.when(BadStaticClass.dontWantThisMethod()).thenReturn(false);
new SomeActivity().usesStatic();
}
}
Basically, i have a class, "SomeActivity", and it has a method that makes a call to BadStaticClass.dontWantThisMethod(). i want that static method to be stubbed out.
why is my code not working?
i kept getting errors like:
you are trying to stub a final method, you naughty developer!
which, i thought the whole point of PowerMock was to not see that.
According to the PowerMock API you have to include #RunWith(PowerMockRunner.class) for certain versions of JUnit, etc. However you also need to be using #RunWith(RobolectricTestRunner.class) and cannot specify more than one #RunWith on a Class.
So what to do?
I suspect you can keep your code above and introduce a JUnit #Rule (see: PowerMockRule docs) and also described in this similar post. Just be sure you check the versions of the Jars you are using so that they match those described in that other SO post. All too often things just won't work unless you get compatible versions, and it's not always obvious what versions are compatible.

Categories