-
Notifications
You must be signed in to change notification settings - Fork 239
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
Mixing Java and Spring annotations. #103
Comments
JMockit does it this way by design, based on the assumption that the code under test would either use standard CDI/Java EE annotations, or proprietary (Spring, Guice) annotations, but not both at the same time. In this case, is there a reason for the SUT to use both @resource and @Autowired? Shouldn't it just use @Autowired, or (ideally) the standard javax.inject.Inject annotation rather than @Autowired? Note that Spring does support @Inject. |
Hi @rliesenfeld, |
Support will be added for @Autowired. |
Hi,
Thanks, |
Hi, You're right about @value; I will add support for it too. About the IllegalStateException, I think this is necessary to avoid unexpected NullPointerExceptions from annotated injection points left uninitialized. Simply printing a warning message to the console will just get ignored by most users. If an existing test breaks, the user can fix it by adding a suitable @Injectable field or parameter. I think this is the right approach because DI containers don't allow required dependencies to remain null either, throwing an exception at startup for any unresolved dependency; also, this prevents a test that passes now to start failing with an NPE months later, when someone changes the code to use the dependency in some new place. |
Hi Rogério, Furthermore lets consider this example
Lets assume that A is nicely covered by unit tests.
I would like to test B in isolation, but in order to do this I need to provide s1 and s2 and s3. Does it make any sense for you? Regards, |
Most classes with injected dependencies shouldn't have more than three or four of them, so it shouldn't be that difficult to declare the necessary @Injectable's. Classes with more than four dependencies are asking to be broken up into smaller classes, so we can argue that the tests are encouraging a better design. For the "B extends A" example, I would say that 1) such cases (where a class with its own tests has a subclass) tend to be rare; 2) testing B in isolation from A implies that A would be mocked away, and that doesn't sound good - either B should be tested as if it doesn't extend A, or object composition should have been used rather than inheritance (then it would be perfecly fine to mock A); and 3) a B instance will have all four dependencies when used in production, so why do differently from the tests? |
Ok, I am fine with this. |
@rliesenfeld Hi Rogerio and thanks for looking into this. I have a few thoughts on the issue. Spring will not autowire an instance of the object into itself unless that field is annotated with @resource. We tend to stick to @Autowired (with possible @qualifier - will you support that?) in most of our services, so that @resource really stands out as self-injection. There's two major cases where do this: @Cacheable proxy and @trace proxy. Now, we've been through all the discussions about the pros and cons of this approach and we stuck to this pattern in certain applications. Our question is really if JMockit will support this. Also, while I agree that mocking framework for Unit Tests should encourage good practices and discourage bad ones, my opinion is that is not its place to enforce them. By encumbering a framework like this with a role of a policeman, you'd be actually discouraging possible new users from adopting it into their legacy applications. There are other tools to enforce good coding practices, some of them exquisitely good. |
@resource was already supported, and now (the next release) it can be used in the same class where @Autowired is used; both annotations, plus @Inject, are supported. I don't know of any use case which requires support for @qualifier, so there isn't any. It shouldn't matter, though, as qualifiers affect only the implementation that would get injected in production, not the type of the mocked dependency used in tests. |
Thanks, that confirms that everything we need is going out in the new release. |
Whenever one mix Java and Spring annotations:
and create a test:
only fields with Java annotations are injected to @tested object.
What I think need to be fixed/redesign is a discardFieldsNotAnnotatedWithJavaxInjectIfAtLeastOneIsAnnotated method inside
mockit.internal.expectations.injection.FieldInjection class
The text was updated successfully, but these errors were encountered: