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'm using Spock to write tests for a Java application. The test includes a JMockit MockUp for the class. When debugging a test (using IntelliJ) I would like to be able to step into the Java code. I realize using F5 to step into the code won't work, because of all the Groovy magic with reflection that goes on. Unfortunately, even if I set a breakpoint in the Java code, it still will not be hit, even though it runs through the code.
Here is the code to test:
public class TestClass {
private static void initializeProperties() {
// Code that will not run during test
}
public static boolean getValue() {
return true; // <=== BREAK POINT SET HERE WILL NEVER BE HIT
}
}
Here is the test code:
class TestClassSpec extends Specification {
void setup() {
new MockUp<TestClass>() {
#Mock
public static void initializeProperties() {}
}
}
void "run test"() {
when:
boolean result = TestClass.getValue()
then:
result == true
}
}
The test passes and everything works well, but I'm not able to debug into the Java code.
Note: I can debug if I do not use the JMockit MockUp, but that is required to test a private static method in my production code.
Any ideas on how to get the debugger to stop in the Java code from a Spock test that uses JMockit?
This answer has plagued me for days, and I have searched and searched for an answer. Fifteen minutes after posting for help, I find the answer . So for anyone else who runs into this, here's my solution - this is all thanks to this answer: https://stackoverflow.com/a/4852727/2601060
In short, the breakpoint is removed when the class is redefined by JMockit. The solution is to set a break point in the test, and once the debugger has stopped in the test THEN set the breakpoint in the Java code.
And there was much rejoicing...
I am using JMockit 1.12 and want to verify that AccessController.doPrivileged() was called. This seems rather straightforward:
#Test(expected = MissingInvocation.class)
public void testFoo1() {
foo(false, true);
}
#Test
public void testFoo2() {
foo(false, false);
}
#Test
public void testFoo3() {
foo(true, true);
}
private void foo(boolean usePrivilegedAccess, boolean expectAccessControllerCall) {
new NonStrictExpectations(AccessController.class) {{
}};
if (usePrivilegedAccess) {
AccessController.doPrivileged((PrivilegedAction<String>) () -> "");
}
// verify AccessController.doPrivileged was called
if (expectAccessControllerCall) {
new Verifications() {{ AccessController.doPrivileged(withAny((PrivilegedAction<Object>) () -> null )); }};
}
}
Note that testFoo1() does not call AccessController.doPrivileged() yet performs the check anyway.
I added this method because I found that sometimes the Verifications block would pass even if AccessController.doPrivileged(). I am using Netbeans 8.0.1 and after a lot of testing, I found that if I run the test using "Run Focused Test Method" or "Debug Focused Test Method" (runs only 1 test) then it passes. If I use "Test File" (runs all tests) then testFoo1() fails because it does not throw MissingInvocation. If I use "Debug Test File" (runs all tests) then it always fails if I put in a breakpoint; it intermittently fails if I do not put in a breakpoint. Very strange.
Is my JMockit usage correct? I am new, so any pointers appreciated but please note that I want to run the exact same test code from 2 tests which only differ by a boolean flag. I do not want to copy/paste the test twice.
Is there something up with Netbeans?
Is it something to do with the CGLib injection somewhere in the pipeline?
What probably happens is that, during the test, AccessController.doPrivileged(...) gets called from somewhere else, perhaps from NetBeans or more likely from the JRE itself.
JMockit 1.x does not restrict the mocking of the AccessController class to just the foo(boolean,boolean) method; instead, it registers all invocations to its methods, regardless of where they come from. The test would have to implement a more restrictive verification, perhaps checking the exact PrivilegedAction instance passed to the mocked method, or even by checking the call stack to see where it comes from.
For JMockit 2, an API change is planned so that mocking gets scoped to #Tested classes only, avoiding situations like this.
I am running tests with uiautomator. When I get to the end of my test, I need to test my results. My problem is of one test fails, the others will not be tested. I need them all to be tested regardless of the results of other test. This is my attempts:
public void testSomeUI() {
////lots of stuff
assertEquals(///assertion///);
assertEquals(///assertion///);
assertEquals(///assertion///);
....and so on
}
Also I tried:
public void testSomeUI() {
////lots of stuff
testValue1();
testValue2();
testValue3();
....and so on
}
private void testValue1(){
assertEquals(///assertion///);
}
private void testValue2(){
assertEquals(///assertion///);
}
private void testValue3(){
assertEquals(///assertion///);
}
..and so on
If one fails, the last three won't run. Any suggestions? Thanks.
Problem is that once an assert fails, it breaks out of the method. That's why the rest don't get run.
Try using a test framework like JUnit (which UIAutomator appears to be built on). Then write one method per assert. That way will you not only get all asserts to run every time, you also break down the tests into suitably small sizes. If they're named properly, you may not need to debug at all, since you can tell by name of the failing test where the problem really is.
Here's a link to a tutorial for example.
I'm having a strange problem with Easymock 3.0 and JUnit 4.8.2.
The problem only occurs when executing the tests from Maven and not from Eclipse.
This is the unit test (very simple):
...
protected ValueExtractorRetriever mockedRetriever;
...
#Before
public void before() {
mockedRetriever = createStrictMock(ValueExtractorRetriever.class);
}
#After
public void after() {
reset(mockedRetriever);
}
#Test
public void testNullValueExtractor() {
expect(mockedRetriever.retrieve("PROP")).andReturn(null).once();
replay(mockedRetriever);
ValueExtractor retriever = mockedRetriever.retrieve("PROP");
assertNull(retriever);
assertTrue(true);
}
And I get:
java.lang.IllegalStateException: 1 matchers expected, 2 recorded.
The weird thing is that I'm not even using an argument matcher. And that is the only method of the test! and to make it even worst it works from Eclipse and fails from Maven!
I found a few links which didn't provide me with an answer:
Another StackOverflow post
Expected Exceptions in JUnit
If I change the unit test and add one more method (which does use an argument matcher):
#Test
public void testIsBeforeDateOk() {
expect(mockedRetriever.retrieve((String)anyObject())).andReturn(new PofExtractor()).anyTimes();
replay(this.mockedRetriever);
FilterBuilder fb = new FilterBuilder();
assertNotNull(fb);
CriteriaFilter cf = new CriteriaFilter();
assertNotNull(cf);
cf.getValues().add("2010-12-29T14:45:23");
cf.setType(CriteriaType.DATE);
cf.setClause(Clause.IS_BEFORE_THE_DATE);
CriteriaQueryClause clause = CriteriaQueryClause.fromValue(cf.getClause());
assertNotNull(clause);
assertEquals(CriteriaQueryClause.IS_BEFORE_THE_DATE, clause);
clause.buildFilter(fb, cf, mockedRetriever);
assertNotNull(fb);
Filter[] filters = fb.getFilters();
assertNotNull(filters);
assertEquals(filters.length, 1);
verify(mockedRetriever);
logger.info("OK");
}
this last method passes the test but not the other one. How is this possible!?!?!
Regards,
Nico
More links:
"bartling.blogspot.com/2009/11/using-argument-matchers-in-easymock-and.html"
"www.springone2gx.com/blog/scott_leberknight/2008/09/the_n_matchers_expected_m_recorded_problem_in_easymock"
"stackoverflow.com/questions/4605997/3-matchers-expected-4-recorded"
I had a very similar problem and wrote my findings in the link below.
http://www.flyingtomoon.com/2011/04/unclosed-record-state-problem-in.html (just updated)
I believe the problem in on another test that affects your current test. The problem is on another test class and it affects you test. In order to find the place of the real problem, I advice to disable the problematic tests one by one till you notify the failing test.
Actually this is what I did. I disabled the failing tests one by one till I found the problematic test. I found a test that throws an exception and catches by "#extected" annotation without stopping the recording.
We had this problem recently, and it only reared its head when we ran the entire test suite (1100+ test cases). Eventually, I found that I could put a breakpoint on the test that was blowing up, and then step back in the list of tests that Eclipse had already executed, looking for the previous test case that had set up a mock incorrectly.
Our problem turned out to be somebody using EasyMock.anyString() outside of an EasyMock.expect(...) statement. Sure enough, it was done two tests before the one that was failing.
So essentially, what was happening is that the misuse of a matcher outside of an expect statement was poisoning EasyMock's state, and the next time we tried to create a mock, EasyMock would blow up.
I believe the first error message
java.lang.IllegalStateException: 1
matchers expected, 2 recorded.
means your mockedRetriever methods called twice but test expects it was called once. So your Eclipse and Maven's configuration differs.
And I have no reason to reset mock after test. Just keep in mind JUnit creates new class instance for every single test method.
EDITED:
What about the reason why the last test method passed the answer is:
expect(mockedRetriever.retrieve((String)anyObject())).andReturn(new PofExtractor()).anyTimes();
But in your first test method it is:
expect(mockedRetriever.retrieve("PROP")).andReturn(null).once();
as equivalent of:
expect(mockedRetriever.retrieve("PROP")).andReturn(null);