-
Notifications
You must be signed in to change notification settings - Fork 31
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
Allow excluding OverrideBean
classes
#59
Conversation
Reinstate `OverrideBean`’s ability to exclude the class its overriding from scanning; now as an annotation option. This allows mock producers, such as: ``` @produces @OverrideBean(exclude = true) @mock SomethingWithInjectedDeps something; ``` To mock the class and while not requiring the mocking of its dependencies.
Hello, from our docs, we state that What is the use case where you need to get rid of the original bean instead of just overriding it? To disable some producer on it? |
In the example code I provided, the idea is that we want to mock The end result is that, with the current code, even though I am mocking the object I still have to satisfy all the dependencies of Allowing exclusion of |
I see, thanks for explanation.
That's designed behaviour though - Rather then twisting this approach with alternatives, I think it would be better to have a look a specialization - can't your mock specialize the original bean? Then you could just add the new bean and it would work out of the box without additional changes. If the answer is no, then we will probably do something as you suggested, only I would aim to document it as |
@manovotn After trying numerous things related to We already have a more "CDI" way of enabling alternatives via I suggest we return Interestingly another thing I noticed is that Once we agree on the correct direction I'll submit a PR to implement the changes. Our current test set requires this exclusion functionality. I only recently discovered the differences when I attempted to switch back to the latest published version. |
FYI, I forgot to explicitly mention why
|
Hmm I can see why specialization doesn't quite cut it for you. It is true that the functionality of Also, your solution of excluding the classes might have certain flaws - it operates on return types which mean that should you return interface as a type, any actual bean with the implementation type will still be "discovered and active", right? That is actually one of the reasons why true specialization requires subclassing as without it you bump into weird situations like this. |
Hey @kdubb!
|
@mkouba The example at the beginning is the example. I'm not adding the bean I want to override manually but the auto-configuration scanning picks it up due to it's The |
@kdubb Ok, so I think I finally understand your use case. I wonder if we could add a special annotation like @EnableAutoWeld
@Exclude(Foo.class) // -> Foo is normally added due to fakeFoo producer field
class ProducesAlternativeTest {
@Produces
@Mock
Foo fakeFoo = new Foo("non-baz");
} |
Returns `OverrideBean` to its previous form and adds a new `ProducesOverride` in its place.
d8b74a2
to
800d6db
Compare
@mkouba Due to the seeming resistance to reverting Using something like your suggested Note At this point |
It's not resistance, there simply wasn't any activity for some while. I checked your PR and have few comments:
|
I stumbled upon this PR looking for a solution for the same problem as kdubb (trying to mock dependencies from injected beans). I actually think the proposed solution could work with a name change of the annotation to @ProduceWithoutScan, @ExcludeFromClassScan or something to that effect. That seems to be what I does and I think it would be enough for me at least. If I added the class again some other way (e.g. addPackages) I would actually prefer an exception. Since then I’ve probably made a mistake. Do you think that would work? |
I don't think this is possible. There is automagical scanning in play which simply will discover the bean and then add all its dependencies. You can see the login inside the I'll have to take yet another look at the proposed solution here and how to actually make it work because last time I checked it didn't work at all. For next release (mid month to end of April?) I would like to have this solved one way or the other. If we can manage to have a supplement for what you need, then I think we should also deprecate Obviously, if you want to contribute, be my guest :) |
@manovotn Apologies, I haven't had time to circle back to this PR. I will say this... you suggested this PR "doesn't work"; it actually does. We are using it currently (actually required for us) in a local version of the project to solve the problem as I've described it. Hopefully I'll get time soon to bring this PR inline with requirements for acceptance. |
Then you probably use different scenario from what I tested. Like I said, I tried to put what was in javadoc into actual test, and that failed to pass. Was a long time ago, so I don't recall the details from the top of my head. |
@manovotn I pushed an example building on the change of @kdubb. I agree with him that his change works (even though the example does not). Hopefully my test will illustrate what I intended (and perhaps also what @kdup intended). I also apologize in advance for any GitHub-mistakes, this was my first push =) |
* Replace `ProducesOverride` with `ExcludeBean` & `ExcludeBeans` to make it clear what the annotation is doing * Implement exclusion via CDI extension that vetos annotated types * Remove `OverrideBean` as it didn’t do what its javadoc explained as well
@manovotn, @erilor Please take a look at my latest changes. I think (hope!) they are something we can all agree upon is a better direction @manovotn You were correct. The code worked in our "complex" cases but didn't work in a simple case; even the simple that was case cited as an example. I've reimplemented exclusion via a CDI extension using veto to address this. I've renamed the annotation to The Javadoc has been changed to describe what it's doing and the limitations of its exclusion abilities have been noted. Hopefully it is clear to all how the annotation works and what its general use case is. I've also implemented 2 simple test cases that validate each of the annotations. Finally, I removed |
Ensure excluded beans are also not scanned for dependencies
@kdubb Works like charm! Would be greate if this could get in to the next release. |
I really like the idea of I also like the idea of removing However, I would remove the |
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.
I think we are nearly there, this looks like the best attempt we have had so far ;)
I've added one comment, but one more thing to note here is that you don't take into consideration CDI qualifiers. That's a problem if you have for instance several impls of Foo
, each with different qualifier(s), but you need to mock only one. In your current state, you would veto()
all of them.
I am not sure this is blocking for us now or if we settle on leaving that unresolved? Handling it will add a lot of complexity and I for instance cannot think of a way to make it work with class level annotation now...
junit5/src/main/java/org/jboss/weld/junit5/auto/ExcludedBeansExtension.java
Outdated
Show resolved
Hide resolved
That's actually good point, it probably better indicates they have contrary meanings.
It is true that they are redundant, however if we ever go into implementing it with qualifiers, it is the method-level annotation that we will need as on the class-level you do not know which variants you replace. Would be interesting to know which of the approaches feels more natural to @erilor and @kdubb as they plan to use them? |
Renaming to @manovotn has the right idea for As to how we use it... currently we don't use |
I agree with @kdubb annotating the method/member feels more natural than @ExcludeBeanClasses. You declare a mock and you want it's class excluded. Maybe if you changed the name of the annotation to @ExcludeBeanClass it would make more clear that it excludes the class and not the actual bean? But then the name won't fit if the functionality is expanded to included hierarchies etc. |
Ok, for initial version, let's not deal with qualifiers. Furthermore please incorporate these changes @kdubb :
Then I think we are good to merge this at long last :) |
* `ExcludeBeans` becomes `ExcludeBeanClasses` and works on specific classes. It is now an “inverse” to `AddBeanClasses` * `ExcludeBean` now excludes based on hierarchy * Tests added for both annotations capabilties * Added not to `ExcludeBean` javadoc about lack of qualifier use when excluding
@manovotn I was in the processing of finishing my last commit when you commented. I had implemented everything but renaming exclude bean. I think what I have is a small bit better when forward looking. First
Finally, I added separate tests for each annotation to test each's expressed capabilities. |
junit5/src/main/java/org/jboss/weld/junit5/auto/ExcludedBeansExtension.java
Show resolved
Hide resolved
Created a backing issue for this #73. I think this looks solid now. We'll include it in next release. |
Nice work everyone and a special thanks to @kdubb for doing the "heavy lifting"! |
Reinstate
OverrideBean
’s ability to exclude the class its overriding from scanning; now as an annotation option. This allows mock producers, such as:To mock the class, while not requiring the mocking of its dependencies.