-
Notifications
You must be signed in to change notification settings - Fork 25
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
[inject-test] Can inject the BeanScope into @InjectTest
tests.
#758
Conversation
What is the motivation for this? BeanScope in component testing has parent/child "layers" and the appropriate BeanScope for a given test depends on what components are injected. So to me this kind of breaks that determination because injecting BeanScope means ANY dependency can be used in the test. So why is this needed? |
Had a guy on the discord that needed to do something like have test beans that also have dependencies on beans from src/main to be used for multiple test classes. Naturally this is currently doesn't fly, so the next best thing is having a utility class that accepts certain beans as parameters. This helps reduce the amount of boilerplate required per test as the utility class can extract all the beans it requires. |
It made sense to me as we can inject the beanscope into regular beans, so why should tests be the exception? |
Hi, I'm the guy on Discord that @SentryMan mentioned. Thank you so much for the suggestions on Discord and for this PR. ❤️ For functional/integration tests this would be really useful. The immediate use case for myself would be some sort of As far as I understand it, the DI lifecycle in tests has two steps:
This makes sense to me, but it would be really useful if the wiring was smart enough to understand that:
On top of this, I can think of many potential use cases where wiring a As SentryMan explained, my current workaround for this is to make my I'm not familiar enough with the codebase to comment on whether this PR solves the issue for me, but I wanted to pitch in on the motivation behind my requests on Discord. I'm also open to the possibility that I could be writing awful tests. 😅 If that's the case, I would appreciate it if you can nudge me in the right direction. |
So wrt ...
You can inject a mock / test double for AuthService in a
Ah, just use Am I misunderstanding?
Yes, that's basically correct.
Which BeanScope is used for a given test depends on what beans are injected into the test [as test doubles / mocks]. If there are no mocks/test doubles ... the test can use the "testAllScope", otherwise a new BeanScope needs to be created for that test, and it uses the "testBaseScope" as its parent - so all the Now this is ok but not ideal in that some components are way more expensive than others - datasources, repositories, databases etc. That is, there is some improvement that I have been thinking about that could be made where we have another "testRepoScope" that contains the relatively expensive components (dataSource etc). In this way tests that provide test doubles don't need to re-wire those more expensive components. This "testRepoScope" would sit between the "testAllScope" and "testBaseScope". It would then be:
... and we'd do this because of the performance benefit, we have enough tests that use mocks/test doubles + leading to the need to wire "relatively expensive" components for each test. I'll suggest that this part is more a side topic to the issue though? |
@rbygrave I spoke to SentryMan on Discord about this.
This PR helps with this workaround because assuming |
Correct. I misunderstood the goal of this PR until I spoke to SentryMan and was just going based off what I was asking on Discord.
I don't want to use |
That is a documentation failure on my part. For an That is, a For example: @Mock HelloData mockData = () -> "ImAConcreteTestDouble"; @Mock HelloData mockData = initMe();
private HelloData initMe() {
// whatever code we want to create the test double
...
return helloData;
} |
Interesting. But I still don't see how that solves the issue. Your example misses one of my issues which is the fact that the In Discord I also noticed another issue where this PR would help. It seems that I can't inject @Test
void test() {
try (BeanScope context = TestBeanScope.builder()
.forTesting()
.build()) {
List<AvajeJavalinPlugin> webRoutes = context.list(AvajeJavalinPlugin.class);
//whatever else
}
} But again, this is a lot of boilerplate. If I could inject the |
So the use case has a test double for AuthService, and this test double wants to make use of the real/injected UserRepository [say in order to assist setting up test data or something like that]. Well, normally no you can't pass the UserRepository into the constructor of the test double but we can indeed set it up post construction say in |
Pull request was closed
Now tests using
@InjectTest
are able to inject the fullBeanScope
into the test.