Java @ComponentScan 无法使用 spring-boot-starter-test 进行测试
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/23701616/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
@ComponentScan not working in test with spring-boot-starter-test
提问by samoussa.usa
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.
我正在尝试使用 spring-boot-starter-test测试我@Service
和@Repository
我的项目中的类,但@Autowired
不适用于我正在测试的类。
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.
单元测试上的注释类注释代表了我试图让它工作的各种事情。测试和项目包位于相同的包路径中,并且@ComponentScan
从我的入口点(@RestController
带有 main 方法的类)开始工作正常。在 src/main/java 端的我的班级中,服务@ComponentScan
的 and@Autowire
很好@RestController
,但在测试中没有。我需要@Bean
在我的@Configuration
班级中再次添加它@Autowired
才能工作。该类在其他范围内很好,我可以从测试中很好地引用和实例化它。问题似乎是@ComponentScan
在我的测试运行程序类路径中似乎没有正确遍历多个条目,在本例中为 /target/test-classes 和 /target/classes。
The IDE I am using is IntelliJ IDEA 13.
我使用的 IDE 是 IntelliJ IDEA 13。
UPDATE- here are HelloWorldRs and its config:
更新- 这里是 HelloWorldRs 及其配置:
@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();
}
}
回答by Dave Syer
I don't know if this will turn out to be the solution, but don't use the default package (i.e. don't put *.java in "src/main/java" directly), and definitely don't use a @ComponentScan
or @EnableAutoConfiguration
in the default package. You will end up killing your application on startup as it tries to scan everything on the classpath (including all the Spring libraries).
我不知道这是否会成为解决方案,但不要使用默认包(即不要将 *.java 直接放在“src/main/java”中),并且绝对不要使用@ComponentScan
或@EnableAutoConfiguration
在默认包中。您最终会在启动时杀死您的应用程序,因为它会尝试扫描类路径上的所有内容(包括所有 Spring 库)。
回答by Marwin
First, I'd recommend to use a newer @RunWith(SpringRunner.class)
but that makes no difference, it is just shorter (and recommended).
首先,我建议使用更新的@RunWith(SpringRunner.class)
但没有区别,它只是更短(并推荐)。
Second, from the @EnableAutoConfiguration
I see that you are using spring boot - which is certainly a good thing. There are some good reasons why notto use @ComponentScan
directly. Can you try the following?
其次,从@EnableAutoConfiguration
我看到您正在使用 spring boot - 这当然是一件好事。不@ComponentScan
直接使用有一些很好的理由。您可以尝试以下方法吗?
@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes=YourApplication_or_other_Configuration.class)
public class HelloWorldTest {
... etc.