I am attempting to test my @Service
and @Repository
classes in my project with spring-boot-starter-test and @Autowired
is not working for the classes I'm testing.
Unit test:
@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = HelloWorldConfiguration.class
//@SpringApplicationConfiguration(classes = HelloWorldRs.class)
//@ComponentScan(basePackages = {"com.me.sbworkshop", "com.me.sbworkshop.service"})
//@ConfigurationProperties("helloworld")
//@EnableAutoConfiguration
//@ActiveProfiles("test")
// THIS CLASS IS IN src/test/java/ AND BUILDS INTO target/test-classes
public class HelloWorldTest {
@Autowired
HelloWorldMessageService helloWorldMessageService;
public static final String EXPECTED = "je pense donc je suis-TESTING123";
@Test
public void testGetMessage() {
String result = helloWorldMessageService.getMessage();
Assert.assertEquals(EXPECTED, result);
}
}
Service:
@Service
@ConfigurationProperties("helloworld")
// THIS CLASS IS IN /src/main/java AND BUILDS INTO target/classes
public class HelloWorldMessageService {
private String message;
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message=message;
}
}
The commented class annotations on the unit test represent the various things I've tried to get this working. The test and the project packages are in the same package paths and the @ComponentScan
works fine from my entry point (@RestController
class with main method). The service @ComponentScan
's and @Autowire
's fine in my @RestController
class in the src/main/java side, but does not in the test. I am required to add it again as a @Bean
in my @Configuration
class in order for @Autowired
to work. The class is otherwise in scope just fine and I can reference and instantiate it just fine from the test. The problem appears to be that @ComponentScan
does not appear to correctly traverse multiple entries in my test runner classpath, in this case /target/test-classes and /target/classes.
The IDE I am using is IntelliJ IDEA 13.
UPDATE - here are HelloWorldRs and its config:
@RestController
@EnableAutoConfiguration
@ComponentScan
public class HelloWorldRs {
// SPRING BOOT ENTRY POINT - main() method
public static void main(String[] args) {
SpringApplication.run(HelloWorldRs.class);
}
@Autowired
HelloWorldMessageService helloWorldMessageService;
@RequestMapping("/helloWorld")
public String helloWorld() {
return helloWorldMessageService.getMessage();
}
}
...
@Configuration
public class HelloWorldConfiguration {
@Bean
public Map<String, String> map() {
return new HashMap<>();
}
// This bean was manually added as a workaround to the @ComponentScan problem
@Bean
public HelloWorldMessageService helloWorldMessageService() {
return new HelloWorldMessageService();
}
// This bean was manually added as a workaround to the @ComponentScan problem
@Bean
public HelloWorldRs helloWorldRs() {
return new HelloWorldRs();
}
}
First, I'd recommend to use a newer @RunWith(SpringRunner.class)
but that makes no difference, it is just shorter (and recommended).
Second, from the @EnableAutoConfiguration
I see that you are using spring boot - which is certainly a good thing. There are some good reasons why not to use @ComponentScan
directly. Can you try the following?
@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes=YourApplication_or_other_Configuration.class)
public class HelloWorldTest {
... etc.