-
-
Notifications
You must be signed in to change notification settings - Fork 2.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Mockito with Groovy fails to create stubs for partial mock for abstract class derivative #1108
Comments
Thank you for reporting! We don't normally use Mockito with Groovy code because the best unit testing framework for Groovy is Spock framework which already contains great support for mocking. By now, did you find a way to resolve the problem? If not, do you want to help identifying the root cause? Can you try with Mockito latest 1.x and see if it works? Mockito 1.x used CGLIB for mocking and I'm wondering if the behavior was the same for this scenario. Also, you can try debugging Mockito code and see in what way the internal behavior is different for the succeeded() and failed() methods. |
First and foremost, thank you very much.
Legacy codebase dictates options. :-(
I was able to convert class to non-abstract, but it was sub-optional.
Absolutely!
I had troubles running 1.9.5 (but probably for unrelated reasons). Let me give it a try.
It is a bit difficult. I am new to Groovy / Java / Mockito world, and not quite sure how to run local build dependency. Decompiled code is not fun to run at all. I will do my best. |
Mockito ships source code to Maven Central. So long you configure your project using model build tools like Gradle or at least Maven, the source code should be picked up automatically by the IDE. Just run test with debugging, and step to the code to debug issues like this one. If you don't feel bold enough to dive into debugging, consider creating a tiny project / repository where the problem can be reproduced. Then perhaps somebody from the core team or some other contributor can pick up the work! I'll mark this ticket as "please-contribute". Thank you for supplying the Test sample - it is very useful for reproducing issues. |
@szczepiq I debugged through the code, looks like byte buddy doesn't work well with Groovy, do you have any suggestions on fixing this? Continuing with the example in this post, in the "failed" test, the |
I've tried with 1.10.19 and 1.9.5 and still getting the same exception. |
I don't have an answer right off the bat. The issue needs to be debugged. I'll ping @raphw (founder of Bytebuddy and core Mockito developer) in case he can / have time to help out. Side question: why don't you use Spock framework for testing and mocking Groovy code? |
Me personally - I think I ended up using Spock. I was evaluating frameworks for a new Groovy project (which is a Jenkins shared library for it's 2.0 Pipelines) and so far Spock looks like a best fit. But from the top of my head the answer could be - this is not a Groovy project but rather a Java project with some Groovy. Even now I still not sure will Spock play nice in terms of mocking when it will come to testing code that is extensively using Java libs such as apache-commons which is Java and built all of a static methods. Hope it will. Otherwise I will have to look at Mockito together with PowerMock once again. |
Might be a little late to contribute, but I was running into a similar issue with the following code: abstract class DAO {}
class PersonDAO extends DAO {
Person findById(Long id)
}
class PersonDAOTest {
@Test
void fails() {
def dao = Mockito.mock(PersonDAO)
Mockito.given(dao.findById(Mockito.anyLong())).willReturn(new Person()) // Fails with a MatchersException
dao.findById(1L)
assertNotNull(person)
}
} What worked for me was converting the abstract class ( |
I found a working workaround. It requires some code changes, but only in tests. You can add the groovy.transform.CompileStatic annotation to the test class. I checked if for the above example. Sourcespackage issue1108
abstract class DAO {} package issue1108
class Person {} package issue1108
class PersonDAO extends DAO {
Person findById(Long id) {
return new Person()
}
} Broken Test Classpackage issue1108
import static org.junit.jupiter.api.Assertions.assertNotNull
import static org.mockito.Mockito.mock
import static org.mockito.Mockito.when
import org.junit.jupiter.api.Test
import org.mockito.Mockito
class PersonDAOTest extends DAO {
@Test
void fails() {
def dao = mock(PersonDAO)
when(dao.findById(Mockito.anyLong())).thenReturn(new Person())
def person = dao.findById(1L)
assertNotNull(person)
}
}
Successful Test Classpackage issue1108
import static org.junit.jupiter.api.Assertions.assertNotNull
import static org.mockito.Mockito.mock
import static org.mockito.Mockito.when
import groovy.transform.CompileStatic
import org.junit.jupiter.api.Test
import org.mockito.Mockito
@CompileStatic
class PersonDAOTest extends DAO {
@Test
void fails() {
def dao = mock(PersonDAO)
when(dao.findById(Mockito.anyLong())).thenReturn(new Person())
def person = dao.findById(1L)
assertNotNull(person)
}
} |
We have a bunch of dynamic class loading happening, can't use |
I added the following comment to a related ticket with a reproducible example, hopefully it is something that can be resolved: |
Groovy 2.5.3 and newer writes |
We use Groovy for Jenkins shared library's. And in Jenkins, the Groovy version is still locked to 2.4.21. https://issues.jenkins.io/plugins/servlet/mobile#issue/JENKINS-51823 Whether or not to invest time into this issue, given that it only affects users of Groovy, and only very old versions of Groovy at that, is a valid question. I will point out that vast numbers of people are using Groovy with Jenkins, and the subset of those which are also trying to use mockito is probably also significant, but that still might not be enough to warrant further investment. |
I am using Mockito 2.8.9 with Groovy 2.4.1 and JUnit 4.12 (openjdk version "1.8.0_131")
The setup:
I have an instance of the
Failure
class that is derived fromabstract
AbstractBase
parent.I am stubbing partial mock (
spy
) usingdoXxx
methods.=> failure
For contrast, the above steps are repeated with
Success
which is derived from regularBase
parent.=> success
The tests:
As test names suggest,
succeed()
works as expected, whilefailed()
generates an error with following message and stack trace (integer is incidental, I verified with several types):Thank you!
P.S. I ran it also with Groovy 2.4.10, and with Mockito 2.7.22 -- with the same result
The text was updated successfully, but these errors were encountered: