-
-
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
automatically detect class to mock #2779
automatically detect class to mock #2779
Conversation
this commit adds method `Mockito.mock()` as a shorter alternative for `Mockito.mock(Class)`. When result of this call is assigned to a variable/field, java will detect the needed class automatically. P.S. I had to ignore errorprone checks "DoNotMock" and "DoNotMockAutoValue" because they fail with IndexOutOfBoundException trying to get the first argument of `Mockito.mock()`. :)
This is a super interesting implementation and I am not sure what to think of it. What I like about That said, I am not sure if there is any harm in shipping this method, given that it does resolve the unchecked warning problem for @mockito/developers WDYT? |
I do like the concept! I am however not sure if overloading might create some issues here and there, but as our tests compile, it does not seem to be a problem. We are already doing a lot with the Java language that is not intuitive at first glance, so I think this would be a good API addition. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a new section to the JavaDoc (section 54) that showcases the new feature. Don't forget to also link to the new section in the Contents section at the top.
This API is similar to the Spock one where it has been in common use for years. If there are no warnings in IDE, why not to leverage it (assuming no technical glitches are found).
is a (current) alternative, but the new one is even more robust (and shorter). Btw, Groovy allows to do that kind of tricks, but I didn't know about that one in Java, good idea @asolntsev! |
Codecov ReportBase: 86.18% // Head: 74.95% // Decreases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## main #2779 +/- ##
=============================================
- Coverage 86.18% 74.95% -11.23%
+ Complexity 2828 2549 -279
=============================================
Files 320 320
Lines 8583 8556 -27
Branches 1060 1044 -16
=============================================
- Hits 7397 6413 -984
- Misses 905 1814 +909
- Partials 281 329 +48
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
I also didn't know that Java can detect the class name. |
... similarly to `Mockito.mock()`
@szpak @TimvdLippe Similarly to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 small nits. I wanted to fix them myself, but I didn't have permission to push to your fork. After that, this LGTM!
Co-authored-by: Tim van der Lippe <TimvdLippe@users.noreply.github.com>
Co-authored-by: Tim van der Lippe <TimvdLippe@users.noreply.github.com>
Thank you, merged. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks!
* | ||
* @param reified don't pass any values to it. It's a trick to detect the class/interface you want to mock. | ||
* @return mock object | ||
* @since 4.9.0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Too late, I know, but shouldn't it have been:
* @since 4.9.0 | |
* @since 4.10.0 |
?
I filed google/error-prone#3609: feel free to adjust as per your own observations. |
This change has broken my Mockito.spy(object_to_mock) calls in a scala project. Basically Scala cant differenciate between the two spy methods. |
@ankurbajaj9 Can you share some reproducible example? I have just tried with Scala 2 and Scala 3 - both |
can you try the Mockito.spy(Object) and see if you can reproduce the same |
@ankurbajaj9 Yes, works for me: @Test def spyWithObject(): Unit = {
val names: util.ArrayList[String] = Mockito.spy(util.ArrayList())
assert(names.size == 0)
names.add("tere")
assert(names.size == 1)
doReturn(42).when(names).size
assert(names.size == 42)
} @ankurbajaj9 Once again: it would be much simpler if you shared some reproducible example. |
We upgraded to a newer version of Mockito (4.11.0, works with 4,9.0) and it breaks our integration test, because I think it takes this new mock method instead of the original one, while it should have executed the original one with this signature public static T mock(Class classToMock). This mock
Causes the following error when creating the applicationcontext for integration tests: This is described as a working way of using Mockito by Spring in their docs:
|
@sijtsche Thank you for reporting the problem.
Anyway, could you please share some simple project to reproduce the problem? Some trivial "hello world" project? |
Yes, I am aware of all types of configuration in Spring. But not all companies use that and it is not even a deprecated way of configuring a Spring application. So IMHO we should be able to use XML configuration in Spring. I think large projects that exists for a long time can not rewrite their whole application wiring because of a Mockito update. So it would be great if we could at least find a workaround. I have created a demo Spring Boot project that reproduces this issue. With a partial solution in XML config too. You will find two testclasses, one that gives the error I mentioned, the other with this workaround that now invokes the right mock method in the Mockito class by specifying the type java.lang.Class:
But, if I add a class to the application context that uses this conversionService mock as an autowired dependency (see TestClass in the testproject) it can not instantiate the TestClass class and fails with this error: Error creating bean with name 'testclass': Unsatisfied dependency expressed through field 'conversionService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.core.convert.ConversionService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)} For that I do not have a workaround (yet). As soon as I set the dependency of mockito-core back to 4.9.0, this works again without other changes. Anyway, you can try it now yourself with this testproject. |
@sijtsche Thank you for providing the working example! <constructor-arg value="org.springframework.core.convert.ConversionService"/> Since Spring doesn't know the type of parameter "ConversionService", it just tries to find a static method with one parameter of any type in class Now <constructor-arg>
<value type="java.lang.Class">org.springframework.core.convert.ConversionService</value>
</constructor-arg> P.S. About your second problem: I think it's not related to the static method |
Hi @asolntsev the typing issue is then solved. But the missing dependency works if I just set mockito back to 4.9.0 it works and if I set it to a higher version it does not work anymore. It indeed probably is not related to this particular change, but I think it is somehow related to Mockito. |
this commit adds method
Mockito.mock()
as a shorter alternative forMockito.mock(Class)
. When result of this call is assigned to a variable/field, java will detect the needed class automatically.P.S. I had to ignore errorprone checks "DoNotMock" and "DoNotMockAutoValue" because they fail with IndexOutOfBoundException trying to get the first argument of
Mockito.mock()
. :)