Closed MFAshby closed 4 years ago
Because the first test passes and not the second I assumed some state must be kept between the tests, so I modified it to reset the spy every time, however I still get the same issue!
private lateinit var underTest: SomeClass
@Before
fun setup() {
underTest = spy(SomeClass())
}
The same test written in java with regular Mockito
works as expected:
package com.mypackage;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import org.junit.Test;
class SomeClass {
public void doThing1() {
doThing2();
}
public void doThing2() {
System.out.println("Hey");
}
}
public class SpyingProblem {
private SomeClass underTest = spy(new SomeClass());
@Test
public void cantVerifySpies() {
// WHEN
underTest.doThing1();
// THEN
verify(underTest, times(1)).doThing2();
}
@Test
public void cantVerifySpies2() {
// WHEN
underTest.doThing1();
// THEN
verify(underTest, times(1)).doThing2();
}
}
Interesting I think this might be something in mockito and not related to this wrapper. If I change the 'production' code to kotlin, and keep the test as java using mockito I get the same error:
SomeClass.kt
package com.pkb.kms.client.core
open class SomeClass {
fun doThing1() {
doThing2()
}
fun doThing2() {
println("Hey")
}
}
SpyingProblem.java:
package com.pkb.kms.client.core;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import org.junit.Test;
public class SpyingProblem {
private SomeClass underTest = spy(new SomeClass());
@Test
public void cantVerifySpies() {
// WHEN
underTest.doThing1();
// THEN
verify(underTest, times(1)).doThing2();
}
@Test
public void cantVerifySpies2() {
// WHEN
underTest.doThing1();
// THEN
verify(underTest, times(1)).doThing2();
}
}
Error logging:
org.mockito.exceptions.misusing.UnfinishedVerificationException:
Missing method call for verify(mock) here:
-> at com.pkb.kms.client.core.SpyingProblem.cantVerifySpies(SpyingProblem.java:20)
Example of correct verification:
verify(mock).doSomething()
I'll raise an issue with mockito instead!
@MFAshby This is because your functions aren't open. They will be in java. Add open
to both functions and it'll work. Otherwise use mockito-inline to enable this on final
methods
@bohsen thanks, this worked!
What is confusing me though: why is it working without open
for a single test? This led me to believe there was some state that was being retained between tests.
What is confusing me though: why is it working without
open
for a single test? This led me to believe there was some state that was being retained between tests.
Can't say. Need an MWE to look at for further investigation if needed. Regarding shared state between unit tests. This is highly unlikely the reason as both JUnit 4 and 5 by default create a new instance of the test class before running each test method.
Minimal working exmple at https://github.com/MFAshby/spying-problem-sample @bohsen if you are in a position to investigate and have some time
Might take a look at it, when I have time.
Thx for the sample and merry Christmas ☃️🎄
@bohsen thanks, have a good one!
I have a test class with 2 tests. The tests are trying to verify the behaviour of the subject by spying on it.
Expected behaviour: tests pass because the expected method call is made.
Actual behaviour: The first test passes, and the second (identical in this sample) test which attempts to verify receives an
UnfinishedVerificationException
Sample code:
Received logging:
mockito-kotlin
version 2.2.0,kotlin
version 1.3.61