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
Configure mocks for annotation interfaces with default values from annotation #1900
Comments
…alues from annotation
Intriguing feature request! Could you elaborate on a concrete example of a test where you would use this? I would assume that any annotation you specify is static and therefore should not be changed. E.g. you should use the real annotation instead of a mock. Would like to know more about that. |
See https://github.com/apache/felix-dev/blob/f51a4a870364db5909bae8704548d028c0945d8b/healthcheck/core/src/test/java/org/apache/felix/hc/core/impl/monitor/HealthCheckMonitorTest.java#L108 for where I added this functionality manually to a concrete test (this JUnit test was the trigger to start the discussion here). In general, everybody developing with the OSGi Metatype Service (see https://osgi.org/specification/osgi.cmpn/7.0.0/service.metatype.html#d0e17824) is using OSGi framework-provided annotation instances to activate components. This may sound unusual, but the OSGi spec chose annotations for this use case because it very well fits to the semantics of what is needed (null not possible, defaults can be given in code, immutable). And as said, for the case Here are some examples from elsewhere to illustrate how those annotations are used with the OSGi Metatype Service: Code: https://github.com/Adobe-Consulting-Services/acs-aem-commons/blob/bc9bda13b6e3cfd5aef6a13cb54b63ede213b06a/bundle/src/main/java/com/adobe/acs/commons/httpcache/config/impl/RequestCookieHttpCacheConfigExtension.java#L69-L87 Or code: https://github.com/apache/sling-org-apache-sling-scripting-core/blob/a9f1b82bbf128cca76cf7ba6cba227d5a282d1f9/src/main/java/org/apache/sling/scripting/core/impl/ScriptCacheImplConfiguration.java#L30-L45 (no JUnit test at all for this, maybe because it is hard to mock it :) ) Overall, see https://github.com/search?q=org.osgi.service.metatype.ObjectClassDefinition+language%3Ajava&type=Code for a github search on where this is used (and this is github only). So I don't think it's too much of an exotic use case, it would be really valuable to have this in Mockito core. |
I understand the desire to fully test the annotations. However, my understanding of annotations is that they should always be attached to a symbol. E.g. they should be attached to a variable or field. Therefore, I don't think allowing instances of annotations to live separate from the symbol they should be attached to is desirable. Instead, using the annotation directly on a Mock can help. Mockito makes sure that any annotations that are attached are preserved on runtime and are present on mocks. Would that work for you? |
Fact is: OSGi Metatype Service (see https://osgi.org/specification/osgi.cmpn/7.0.0/service.metatype.html#d0e17824 ) makes use of annotations without ever attaching it to a symbol (not in declaration, not in usage). Java as language chose to implement annotations as a special type of interface (while still having all properties of an interface + some extra traits => immutability, default values, etc.). OSGi chose to use those traits without actually using the annotation part itself. Now, to accommodate the nature of the annotation implementation in java, this PR makes perfectly sense.
when using annotations directly on a symbol, you create immutable objects. To test all value combinations of an annotation this quickly becomes tedious because all value combinations have to be explicitly listed: Given the annotation
Using the annotation in a test connecting it to a symbol is cumbersome:
By using a mock for this, the code becomes a lot cleaner:
Now for this trivial example it might not even look that bad, but in OSGi metatype config annotations it can easily get to 10 member methods (many combinations if you cannot use |
@TimvdLippe So I think think this PR would improve Mockito to be in line with the annotation implementation the java platform chose. Also because of the |
Bumpl! |
👍 I have the same issue, it would be nice that mockito would detect and automatically mock those default, so that it would not look suspicious in the test code that it force the mock with when/ thenReturn.. |
Mockito.mock()
can quite conveniently be used to not only create instances of interfaces, but also to create instances of annotation interfaces. Although normally those instances are created by using the annotations in source code (and subsequently usingclass.getAnnotations()
, often in framework code) there are some use cases where the annotation instances are created by a framework - in particular this is the case for the OSGi Metatype Service (see https://osgi.org/specification/osgi.cmpn/7.0.0/service.metatype.html#d0e17824 for details). For this use case, a mock for an annotation interface should be automatically set up to return the annotation-defined default values.The following JUnit Tests illustrates what is needed:
The text was updated successfully, but these errors were encountered: