5

My problem: if my test refers to an @Bean declaration in the class listed in @SpringBootTest, autowire works. If it refers to a class automatically @ComponentScanned by the class listed in @SpringBootTest, autowire fails. Outside of testing, my app starts without autowire or componentscan issues, and I can confirm that the service I want to load in my test runs fine from non-test. I'm frustrated as hell. Am I broken, or is Junit5 functionality on Spring Boot 2?

My Test:

@ExtendWith(SpringExtension.class)
@SpringBootTest (classes=MyConfig.class)
public class MyTest {
    // fails to autowire
    @Autowired
    private MyService _mySvc ;

    // succeeds!
    @Autowired @Qualifier ( "wtf" )
    private String _wtf ;

MyConfig:

@EnableWebMvc
@SpringBootApplication ( scanBasePackages = "my.packaging" )
@Configuration
public class MyConfig {

    @Bean
    public String wtf ( ) { return "W T F???" ; }

    // No @Bean for MyService because component scan is nicer in the non-test world
billmill
  • 331
  • 1
  • 3
  • 14

4 Answers4

13

I had the same issue with autowiring not working although the test was starting and the problem was that I was still using the old junit4 @Test annotation. Make sure your test method is annotated with @Test from juni5 package org.junit.jupiter.api.Test.

Tudro
  • 186
  • 1
  • 5
2

I think because you have annotated as such:

@SpringBootTest (classes=MyConfig.class)

Spring will only look in MyConfig.class for the appropriate beans and is not able to find one for MyService, however, I presume that Spring will scan all packages for a bean when the application is running normally. This is why it works fine in non-test.

Adam Beddoe
  • 153
  • 2
  • 10
  • 1
    Interesting. How do I get it to then scan the packages I need scanned, if MyConfig is already a Configuration with a scanner enabled? – billmill Sep 19 '18 at 18:00
  • Maybe try adding the `@ComponentScan` annotation to the test class. - I'm not very familiar with Spring testing annotations, usually set it up once for what I need each project and then forget how it works – Adam Beddoe Sep 20 '18 at 08:22
  • @billmill If you only annotate your class with `@SpringBootTest` it will first check if there is a nested `@Configuration` class available and if not fallback to automatically look for classes annotated with `@SpringBootConfiguration` within the classpath, `@SpringBootApplication` is i.e. annotated with `@SpringBootConfiguration` and therfore should be found. If you provide classes via `@SpringBootTest` then these classes are taken instead of letting Spring determine the actual Spring boot application classes. – Roman Vottner Sep 21 '18 at 12:27
0

Like @Tudro said, org.junit.jupiter.api.Test is for Junit 5. org.junit.Test is for Junit 4.

Use this below:

@ExtendedWith(SpringExtension.class)
@SpringBootTest
Haneul
  • 9
  • 1
0

Maybe you could add @ContextConfiguration(classes = ApplicationConfiguration.class)

It would look like this

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ContextConfiguration;
import example06.junit.group01.Piano;

@SpringBootTest
@ContextConfiguration(classes = ApplicationConfiguration.class)
public class ApplicationConfigurationTest {
    @Autowired
    private Piano piano;
    
    @Test
    public void shouldTestPiano() {
        System.err.println("Testing JUnit5 > " + piano);
    }
}

My config is a simple class

@Configuration
@ComponentScan
public class ApplicationConfiguration {

}
Renzo
  • 11
  • 2