Mockito appears to be throwing an UnfinishedVerificationException when I think I've done everything correctly. Here's my partial test case:
HttpServletRequest req = mock(HttpServletRequest.class);
when(req.getHeader("Authorization")).thenReturn("foo");
HttpServletResponse res = mock(HttpServletResponse.class);
classUnderTest.doMethod(req, res); // Use the mock
verify(res, never());
verify(req).setAttribute(anyString(), anyObject());
And here's the partial class and method:
class ClassUnderTest extends AnotherClass {
#Override
public String doMethod(ServletRequest req, ServletRequest res) {
// etc.
return "someString";
}
}
Ignoring the fact that you should never mock interfaces you don't own, why is Mockito giving me the following message?
org.mockito.exceptions.misusing.UnfinishedVerificationException:
Missing method call for verify(mock) here:
-> at (redacted)
Example of correct verification:
verify(mock).doSomething()
Also, this error might show up because you verify either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
at [test method name and class redacted]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.mockito.internal.runners.JUnit45AndHigherRunnerImpl.run(JUnit45AndHigherRunnerImpl.java:37)
at org.mockito.runners.MockitoJUnitRunner.run(MockitoJUnitRunner.java:62)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
... etc
This might also be caused if you try to verify a method which expects primitive arguments with any():
For example, if our method has this signature:
method(long l, String s);
And you try to verify it like this, it will fail with aforementioned message:
verify(service).method(any(), anyString());
Change it to anyLong() and it will work:
verify(service).method(anyLong(), anyString());
I just came across this my self and it caused me a lot of confusion.
As David mentioned above Mockito reports errors in the next Mockito method call which may not be in the same test method. While the exception message does contain a reference to the actual place the error occurred I find having incorrect tests failing counter productive to the testing process. And the simpler the tests the more likely an error is to show up in the next test!
Here is an easy fix that will ensure errors appear in the correct test method:
#After
public void validate() {
validateMockitoUsage();
}
From the Mockito documentation here:
Mockito throws exceptions if you misuse it so that you know if your
tests are written correctly. The gotcha is that Mockito does the
validation next time you use the framework (e.g. next time you verify,
stub, call mock etc.). But even though the exception might be thrown
in the next test, the exception message contains a navigable stack
trace element with location of the defect. Hence you can click and
find the place where Mockito was misused.
Sometimes though, you might
want to validate the framework usage explicitly. For example, one of
the users wanted to put validateMockitoUsage() in his #After method so
that he knows immediately when he misused Mockito. Without it, he
would have known about it not sooner than next time he used the
framework. One more benefit of having validateMockitoUsage() in #After
is that jUnit runner will always fail in the test method with defect
whereas ordinary 'next-time' validation might fail the next test
method. But even though JUnit might report next test as red, don't
worry about it and just click at navigable stack trace element in the
exception message to instantly locate the place where you misused
mockito.
I was getting this same error due to using any() with a boolean parameter, when apparently it needed to be anyBoolean().
In my case, using kotlin was because the funcion to test was not declared as open.
The exception notices that no final/private/equals/hash methods can be used.
fun increment(){
i++
}
to
open fun increment(){
i++
}
With Junit 5, you can add the following to show more meaningful Mockito exceptions in the console
#AfterEach
public void validate() {
validateMockitoUsage()
}
Also see this answer: https://stackoverflow.com/a/22550055/8073652
I had similar exception with class MyRepository
org.mockito.exceptions.misusing.UnfinishedVerificationException:
Missing method call for verify(mock) here:
-> at MyRepository$$FastClassBySpringCGLIB$$de8d8358.invoke()
Example of correct verification:
verify(mock).doSomething()
The problem was resolved when I created interface for MyRepository, and mock interface, but not implementation.
It seems spring creates some CGLIB proxies and it leads to UnfinishedVerificationException exception.
For me the issue turned out to be a missing bean declaration in the test context xml. It was for a custom aspect class used by another class, an instance of which is a parameter to the constructor of the class which is the parameter to failing verify() call. So I added the bean declaration to the context xml and it worked fine after that.
Changed to #RunWith(PowerMockRunner.class) and the issue went away.
Was using #RunWith(MockitoJUnitRunner.class) earlier.
Hope that helps someone..
I had the same issue, too, on the following stack:
Kotlin
Junit 4.13
Mockito 2.28.2 + Mockito-Inline 2.13.0
Robolectric 4.3.1
I tried to verify a lambda call:
#RunWith(RobolectricTestRunner::class)
class MainViewTest {
#get:Rule
val mockitoRule: MockitoRule = MockitoJUnit.rule()
#Mock private lateinit var mockClickCallback: () -> Unit
#Test
fun `should call clickCallback on the button click`() {
val activity = Robolectric.buildActivity(MainActivity::class.java).create().get()
val viewUnderTest = MainView(activity)
viewUnderTest.setClickCallback(mockClickCallback)
viewUnderTest.button.performClick()
verify(mockClickCallback).invoke() // UnfinishedVerificationException
}
}
Then I found the issue on Github, it seems that the problem is in Robolectric. I used the following workaround:
#RunWith(RobolectricTestRunner::class)
class MainViewTest {
private interface UnitFunction: () -> Unit
#Test
fun `should call clickCallback on the button click`() {
val activity = Robolectric.buildActivity(MainActivity::class.java).create().get()
val viewUnderTest = MainView(activity)
val mockClickCallback = mock(UnitFunction::class.java) as () -> Unit
viewUnderTest.setClickCallback(mockClickCallback)
viewUnderTest.button.performClick()
verify(mockClickCallback).invoke() // OK
}
}
Two answers above suggested using validateMockitoUsage() method after each test.
While this is correct I found that annotating your class with #ExtendWith(MockitoExtension.class)
in Junit 5 give the same effect while adding some the nice Mockito functionalities. Also, it looks cleaner to me as well.
I guess Junit 4 #RunWith(MockitoJUnitRunner.class) will give a similar result but I didn't test it.
I had a similar problem, i found a way to solve this. Mock objects which you for verify haven't been reseted, so you should reset it .You can reset(mock) before your test case function, it may be helpful.
If you try to verify a private or package-private method with Mockito.verify you will get this error.
If you don't want to use PowerMockito you can set your method as protected and I advise you to add the #VisibleForTesting tag:
Before:
void doSomething() {
//Some behaviour
}
After :
#VisibleForTesting
protected void doSomething() {
//Some behaviour
}
I was having the same error
org.mockito.exceptions.misusing.UnfinishedVerificationException:
Missing method call for verify(mock) here:
-at com.xxx.MyTest.testRun_Should_xxx_When_yyy(MyTest.java:127)
Example of correct verification:
verify(mock).doSomething()
Also, this error might show up because you verify either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
Mocking methods declared on non-public parent classes is not supported.
at com.xxx.MyTest.validate(MyTest.java:132)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.internal.runners.MethodRoadie.runAfters(MethodRoadie.java:145)
at org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:99)
...
In my case, the error was generated because I was using a PowerMockito.verifyStatic() before my Mockito.verify(...) call, then I had to move the PowerMockito.verifyStatic() to last line (or delete it).
From:
PowerMockito.verifyStatic();
Mockito.verify(myMock, Mockito.times(1)).myMockedMethod(anyString(), anyString(), anyString(), any(XXX.class), any(YYY.class), any(ZZZ.class));
To:
Mockito.verify(myMock, Mockito.times(1)).myMockedMethod(anyString(), anyString(), anyString(), any(XXX.class), any(YYY.class), any(ZZZ.class));
PowerMockito.verifyStatic();
Here is my grain of salt!
I discovered there is a conflict between Mockito and Hibernate Validation.
My solution is the separate my contract checks (#NotNull, #NotEmpty, etc) from the mockito tests. I also started using validateMockitoUsage() to ensure everything was run correctly.
The tests run individually well but while running integration test suite it fails with the UnfinishedVerificationException. The issue arises when we use verify() from mockito and have #EnableRetry.
Workaround for this is to use
public static <T> T unwrapAndVerify(T mock, VerificationMode mode) {
return ((T) Mockito.verify(AopTestUtils.getTargetObject(mock), mode));
}
as mentioned in Mocked Spring #Service that has #Retryable annotations on methods fails with UnfinishedVerificationException
I'm not sure where are your "classUnderTest" come from, but please keep sure it's mocked, not a real one.
I have the same issue for my test case below:
MyAgent rpc = new MyAgent("myNodeName");
...
rpc.doSomething();
...
PowerMockito.verifyPrivate(rpc).invoke("initPowerSwitch");
PowerMockito.verifyPrivate(rpc).invoke("init", "192.168.0.23", "b2", 3);
But it's disappeared for the following test case:
MyAgent rpc = PowerMockito.spy(new MyAgent("myNodeName"));
...
rpc.doSomething();
...
PowerMockito.verifyPrivate(rpc).invoke("initPowerSwitch");
PowerMockito.verifyPrivate(rpc).invoke("init", "192.168.0.23", "b2", 3);
Attention, the Object rpc should be mocked by PowerMockito.spy(...).
Faced same exception when used mockStatic method and called Mockito.verify multiple times, but passed interface instead of implementing class.
wrong code:
try (MockedStatic<Service> staticMock = Mockito.mockStatic(Service.class, Mockito.CALLS_REAL_METHODS)) {
staticMock.verify(() -> ServiceImpl.method()); // passed without errors
staticMock.verify(() -> ServiceImpl.method()); // throws UnfinishedVerificationException
}
fixed code:
try (MockedStatic<ServiceImpl> staticMock = Mockito.mockStatic(Service.class, Mockito.CALLS_REAL_METHODS)) {
staticMock.verify(() -> ServiceImpl.method());
staticMock.verify(() -> ServiceImpl.method());
}
It was my mistake obviosly, but UnfinishedVerificationException message was not helpfull
Related
So, I am trying to unit test a class in various scenarios. We use JUnit V 4.
I have a setUp method wherein i reStub the mock to return an expected mock Value.
I have 4 tests : test1-test4. test1,test2 work fine with the expected mocked value configured in perTestSetup method.
Test t3 needs MockClass to throw an exception, so i configure it seperately in t3. Now t3 works fine as the mock throws the exception as expected.
But when perTestSetup tries to reset the mock to return mockResult before running test4, it fails and throws the same Runtime exception configured in t4. I also tried reset() before mocking in perTestSetup(). But that too fails similarly.
What am i missing here?
#Before
public void perTestSetup(){
when(MockClass.functionCall(...)).thenReturn(mockResult);
}
#Test
public void test1(){
}
#Test
public void test2(){
}
#Test
public void test3(){
when(MockClass.functionCall(...)).thenThrow(new RuntimeExcption());
...
}
#Test
public void test4(){
}
Your perTestSetup() method isn't doing what you think it is doing. The #Before annotation means the test environment will run this method once, before doing any of the tests, rather than once per test. Before I finished reading your question, I was actually itching to advise you to rename this method to simply setup(), as that would be a more accurate description.
Options:
Change the annotation to #BeforeEach, which would then change the behaviour to do what you think it should currently be doing. However, this would be inefficient as in the second two tests you will be defining behaviour and then immediately redefining it.
What do the parameters look like in your functionCall(...)? It may be possible to define two separate behaviours in your single #Before setup() method, i.e.
when(MockClass.functionCall(good values)).thenReturn(mockResult);
when(MockClass.functionCall(bad values)).thenThrow(new RuntimeException());
In each test, call functionCall() with the relevant values for that that particular test.
If the parameters in functionCall() do not readily accommodate the previous approach, consider making two separate instantiations of MockClass, something like
MockClass successfulMockClass = new mock(MockClass.class);
when(successfulMockClass()).thenReturn(mockResult);
MockClass unsuccessfulMockClass = new mock(MockClass.class);
when(unsuccessfulMockClass()).thenThrow(new RuntimeException());
In your tests, call on the relevant mocked object depending on what input you are testing against.
Without being able to see the details of your class, I suspect the second option is what I would go for. It may be worth trying all three to see which feels most intuitive for you, though.
Im trying to create mock method to run Unit test for function below:
class SomeClass{
fun <T> someMethod(str: String, action: (String) -> T): T {
// do something
return action(str);
}
}
My mock method:
val mock = Mockito.mock(SomeClass::class.java)
`when`(mock.someMethod<Unit>(anyString(), any())).then { invocation ->
#Suppress("UNCHECKED_CAST")
(invocation.arguments[1] as (String) -> Unit).invoke("Some String...")
}
but I meet the following issue, when running it failed and throw exception: java.lang.IllegalStateException at line "when(mock.someMethod(anyString(), any())).then { invocation ->"
do you have any idea to fix it?
Thank for your help
First of all: Using Mockito directly from Kotlin is annoying, e.g. because when is a keyword in the language and you have to escape it using backticks. There is a wrapper library which fixes most of the issues: https://github.com/nhaarman/mockito-kotlin. Otherwise, mockk is a good alternative mocking framework as well.
Regarding your problem:
It is probably related to the fact that Mockito and Kotlin don't work too well together; it works for me using the library mentioned above. Can you share more information about the error message?
I'm writing some unit test and I stumble accross this strange "bug" which prevent me from running my unit test.
When I run the "when(...).thenReturn(...)", I receive a InvocationTargetException. Then strange things is that when I debug, it goes into the real object and crash on a null member. When I debug other "when", it goes in a function called "Intercept" which prevent to go in the real code... I don't understand what is different with this object and how to prevent this weird behavior.
Here is my unit test:
#Test
public void getSyncStatusShouldReturnValueFromDiskWhenNotRunning() throws IOException {
//Arrange
when(updater.isDone()).thenReturn(true);
when(brandSyncUpdater.isDone()).thenReturn(true); //This is where it throw error
when(stationSyncUpdater.isDone()).thenReturn(true);
//Act
//Assert
}
Here is my setUp() and member section of my unit class test
private Updater updater;
private BrandSyncUpdater brandSyncUpdater;
private StationSyncUpdater stationSyncUpdater;
#Before
public void setUp() {
updater = mock(Updater.class);
brandSyncUpdater = mock(BrandSyncUpdater.class);
stationSyncUpdater = mock(StationSyncUpdater.class);
}
I don't know if it's related but the BrandSyncUpdater and StationSyncUpdater both have a parent called SyncUpdater where the isDone() function is located.
EDIT
Hierarchy of class
Updater is a class on its own
BrandSyncUpdater and StationSyncUpdater are extending SyncUpdater
Updater isDone() signature and code:
public boolean isDone() {
return states.isEmpty();
}
SyncUpdater isDone() signature and code:
public boolean isDone() {
return currentStates.isEmpty();
}
EDIT 2
Here is the stack traces of the error in the console. You'll notice that the error here is a "NullPointerException" because it try to use the variable currentStates. But when debugging, the error thrown by mockito is InvocationTargetException.
java.lang.NullPointerException
at com.stingray360.clap.synchronizer.contentcontroller.queue.SyncUpdater.isDone(SyncUpdater.java:117)
at com.stingray360.clap.synchronizer.contentcontroller.queue.BrandSyncUpdater.isDone(BrandSyncUpdater.java:15)
at com.stingray360.clap.synchronizer.contentcontroller.SyncDispatcherTest.getSyncStatusShouldReturnValueFromDiskWhenNotRunning(SyncDispatcherTest.java:190)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:68)
I just found the problem by error trying something else.
My SyncUpdater class wasn't public (it was package). So when trying to use Reflection, it got stuck and throw this weird error.
Thanks for the help of people in the comments!
I was able to fix the same issue by adding the following code snippet to the test Class.
#ObjectFactory
public IObjectFactory getObjectFactory() {
return new PowerMockObjectFactory();
}
I also got this error. In my case i missed #RunWith(PowerMockRunner.class) for my Class (i know it is silly mistake, but wasted few hours troubleshooting everything else :) ).
#RunWith(PowerMockRunner.class)
public class SimpleServiceUpgradeManagerTestNotUsed {
//Class content
}
I also met this kind of exception, the reason is I didn't initialize the class to which the method I mocked belongs.
I encountered the same problem with codes below
catch (final HttpStatusCodeException e)
After I remove the final before HttpStatusCodeException, the Junit test works fine.
And I just use Mockito, no PowerMock
I implement a handler which extends SimpleChannelHandler, and overrides some methods such as channelConnected, messageReceived. However, I am wondering how to unit test it?
I searched about "netty unit test" and found one article which said considering CodecEmbedder, but I am still not sure how to begin. Do you have any example or advice on how to unit test Netty code?
Thanks a lot.
In Netty, there are different ways to test your networking stack.
Testing ChannelHandlers
You can use Netty's EmbeddedChannel to mock a netty connection for testing, an example of this would be:
#Test
public void nettyTest() {
EmbeddedChannel channel = new EmbeddedChannel(new StringDecoder(StandardCharsets.UTF_8));
channel.writeInbound(Unpooled.wrappedBuffer(new byte[]{(byte)0xE2,(byte)0x98,(byte)0xA2}));
String myObject = channel.readInbound();
// Perform checks on your object
assertEquals("☢", myObject);
}
This test above tests for StringDecoder ability to decode unicode correct (example from this bug posted by me)
You can also test the encoder direction using EmbeddedChannel, for this you should use writeOutBound and readInbound.
More Examples:
DelimiterBasedFrameDecoderTest.java:
#Test
public void testIncompleteLinesStrippedDelimiters() {
EmbeddedChannel ch = new EmbeddedChannel(new DelimiterBasedFrameDecoder(8192, true,
Delimiters.lineDelimiter()));
ch.writeInbound(Unpooled.copiedBuffer("Test", Charset.defaultCharset()));
assertNull(ch.readInbound());
ch.writeInbound(Unpooled.copiedBuffer("Line\r\ng\r\n", Charset.defaultCharset()));
assertEquals("TestLine", releaseLater((ByteBuf) ch.readInbound()).toString(Charset.defaultCharset()));
assertEquals("g", releaseLater((ByteBuf) ch.readInbound()).toString(Charset.defaultCharset()));
assertNull(ch.readInbound());
ch.finish();
}
More examples on github.
ByteBuf
To test if you use your bytebufs, you can set a JVM parameter that checks for leaked ByteBuf, for this, you should add -Dio.netty.leakDetectionLevel=PARANOID to the startup parameters, or call the method ResourceLeakDetector.setLevel(PARANOID).
I have the following test to verify that my repository is calling it's respective session (I've rewritten it to highlight the actual problem):
[Test]
public void Why_Does_This_Fail()
{
var objectUnderTest = new SomeGenericsProblem();
var fakeSession = MockRepository.GenerateMock<ISession>();
fakeSession.Expect(s => s.Query<SomeClass>());
objectUnderTest.NotWorking<SomeClass>();
fakeSession.AssertWasCalled(t => t.Query<SomeClass>());
}
but when I run the test I get this:
System.InvalidOperationException :
Invalid call, the last call has been
used or no call has been made (make
sure that you are calling a virtual
(C#) / Overridable (VB) method).(C#) / Overridable (VB) method).
Any ideas what I'm doing wrong here? The session that I'm mocking is an interface, so it has to be virtual/overridable.
I have a feeling it has something to do with the fact that my Query method is a generic, but I don't know any other way to express what I'm trying to test.
Also, If I remove the part that sets up the expectation (i.e. this line of code:)
fakeSession.Expect(s => s.Query<SomeClass>());
I get a different exception which is equally confusing to me:
System.InvalidOperationException : No
expectations were setup to be
verified, ensure that the method call
in the action is a virtual (C#) /
overridable (VB.Net) method calloverridable (VB.Net) method call
So I figured out what was wrong.
ISession comes from NHibernate, which I probably should have mentioned.
The reason why this is cruicialy important is because
session.Query<T>
(which is what I'm trying to mock), is an EXTENSION METHOD.
Rhino Mocks apparently does not have the capability of mocking extension methods, hence why it's giving me the weird error.
So hopefully I'll have saves someone else the time and agony I've gone through in trying to figure out why my test won't pass.
The only solution that I've read about for this is to actually change the design of the extension method (which I can't do because it's part of NHibernate), or to use a different mocking framework like TypeMock.
[Test]
public void Query_WhenCalled_CallsSessionQuery()
{
// arrange
var session = MockRepository.GenerateStub<ISession>();
var r = new Repository(session);
// act
r.Query<SomeClass>();
// assert
session.AssertWasCalled(s => s.Query<SomeClass>());
}