-
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Fixes #1516 and #1631 : Allows @Spy with @InjectMocks to be injected into other @InjectMocks #1711
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
base: main
Are you sure you want to change the base?
Conversation
Codecov Report
@@ Coverage Diff @@
## release/3.x #1711 +/- ##
==================================================
- Coverage 86.84% 12.16% -74.68%
+ Complexity 2518 318 -2200
==================================================
Files 316 310 -6
Lines 6622 6525 -97
Branches 829 826 -3
==================================================
- Hits 5751 794 -4957
- Misses 672 5603 +4931
+ Partials 199 128 -71
Continue to review full report at Codecov.
|
Hi, I've rebased code onto current version 3.3.2. Can I do something to help you more on this PR? |
Hi guys, Will you support this future soon or you already merged this via another PR? I have tested but @SPY and @Injectmocks objects didn't inject to the other @InjectsMocks object |
…o be injected into other @Injectmocks
85c7333
to
ecb8743
Compare
Hi, @adilkaraoz, afaik there is no other PR superseding this one, I hope Mockito guys will have time to to review this PR and offer us this new powerful feature in next release ;) |
Hi @mockitoguy @TimvdLippe @bric3 Please don't let this PR take the dust, I know it's a big PR to review but I made this one 2 years ago and each rebase is a pain... And of course, I'm sure this feature will be useful for users! |
Hey, sorry for the late reply. I think the primary reasons this PR has become stale are the fact that it is very large (e.g. very difficult to review) and it concerns So truth be told, I am not sure if we will be able to make any progress here anytime soon and that it remains in the current state as it is 😢 You have definitely put a lot of effort in this PR already, which is why I would like the answer to be different, but at the same time I have to be realistic in both its size and intended purpose given the wider scope of Mockito. |
[This PR is a cherry pick of #1710 to release/3.x]
check list
including project members to get a better picture of the change
commit is meaningful and help the people that will explore a change in 2 years
Fixes #<issue number>
in the description if relevantFixes #<issue number>
if relevantThis PR aims to fix #1516 and #1631. I know and understand dependency injection is not priority of Mockito team but discussion on #1518 convinces me to propose a fix. Like @mockitoguy I think DI in Mockito is useful and most of reported issues denote users high expectations for a helpful feature rather than the fact it's broken.
Basically this PR allows fields annotated with @SPY and @Injectmocks to be injected into other fields annotated with @Injectmocks and so on.
It may also be a response to #174, the need to a @real annotation, actually I think most usage of @SPY and @Injectmocks combination is a workaround to such annotation.
Because PR ended to change a bunch of classes, I will highlight main changes.
"Entry point" of changes is InjectingAnnotationEngine, I add a loop of mock injection. The loop uses variants of existing field injection strategies documented in DefaultInjectionEngine.
To facilitate field injection strategies variants (StrictConstructorInjection and LenientPropertyAndSetterInjection), I merge ConstructorArgumentResolver (contract to find constructor arguments) and ConstructorInstantiator (contract to find and instantiate constructor) interfaces into an unique ConstructorResolver interface representing a strategy to find a constructor and its arguments. Constructor instantiation part comes back into FieldInitializer.
The fact to merge these two interfaces into ConstructorResolver leads to a better separation of concerns between finding constructor and its arguments in one side and instantiation, initialization and field injection on the other side. isResolvable() allows some tuning between the inclination of strategy implementations to fail with exception or handle failure softly. Moreover it's opening future smarter behaviors, for example BiggestConstructorResolver could try to resolve biggest constructor matching actual available mocks.
I hope you will appreciate this work.