spring-projects / spring-framework

Spring Framework
https://spring.io/projects/spring-framework
Apache License 2.0
55.27k stars 37.62k forks source link

Boilerplate-less SpringJUnitConfig #32739

Closed michaldo closed 2 weeks ago

michaldo commented 2 weeks ago

My Spring application has many beans, logically segregated in Java packages (f.e. order, product, etc.). I would like to test each package in isolation. I would like to start all beans from the package as simple as possible.

It seems that best choice is @SpringJUnitConfig. The annotation starts a context, but without help it does not know where to find beans. It is not easy to help the annotation.

Let's start from beginning. You are @SpringJUnitConfig. You have to start a context, but you have no any hint about beans. Where beans may located? Hmm, in current package?

My solution: if I have package com.company.order with beans, I can write test

package com.company.order;

@SpringJUnitConfig
@ComponentScan
@Import({})
class OrderTest {

    @Test
    void test(@Autowired OrderService orderService) {
        ...

I woild like

package com.company.order;

@SpringJUnitConfig 
class OrderTest {

    @Test
    void test(@Autowired OrderService orderService) {
        ...

I could try to implement it myself, but I need a hint how to start

snicoll commented 2 weeks ago

Thanks for getting in touch, but it feels like this is a question that would be better suited to Stack Overflow. As mentioned in the guidelines for contributing, we prefer to use the issue tracker only for bugs and enhancements. Feel free to update this issue with a link to the re-posted question (so that other people can find it) or add some more details if you feel this is a genuine bug.

michaldo commented 2 weeks ago

@snicoll then let's treat this issue a bug

Test

package com.company.order;

@SpringJUnitConfig
@ComponentScan
class OrderTest { ...

does not find any bean in package com.company.order

Test

package com.company.order;

@SpringJUnitConfig
@ComponentScan
@Import({})
class OrderTest { ...

finds all beans in the package.

It does not make a sense, because empty @Import should be neutral to the test. From abstract logic perspective, behavior should be the same, regardless of presence empty @Import From pragmatic logic perspective, if I add @ComponentScan to the test, it should be respected

snicoll commented 2 weeks ago

@michaldo it doesn't work like that. You can't decide something is a bug without a reasonable explanation. The @Import side effect is interesting (I haven't checked that myself). The first sentence of @ComponentScan states:

Configures component scanning directives for use with {@link Configuration @Configuration} classes.

A test is not a configuration class. @SpringJUnitConfig is what triggers your test to use Spring via @ContextConfiguration. The Javadoc of that class is plentiful so please review it and, if you have more questions, ask them on StackOverflow.

michaldo commented 2 weeks ago

if you have more questions, ask them on StackOverflow.

I do not like ask on SO. First, SO is for concrete problems, not discussions. Second, it does not work: I asked https://stackoverflow.com/q/78383825/2365727 a week ago and no response

The @Import side effect is interesting

Intellij highlights @Autowired private OrderService orderService as "No bean found". It seems Intellij better understood @ComponentScan rules than Spring Test Framework :)

michaldo commented 2 weeks ago

I think that the following formula

package com.company.order;

@SpringJUnitConfig(classes = OrderTest class)
@ComponentScan
class OrderTest { ...

is compact, compliant with @ContextConfiguration rules and does not confusing for Intellij like version with empty @Import.

Although super compact @SpringJUnitConfig class OrderTest { ... looks better, I do not see opportunity to be implemented. It is strange, because similar org.springframework.modulith.test.ApplicationModuleTest can scan package out of the box without any extra parameters.

Anyway, compact version is acceptable and I'm fine to close this issue