我遇到了自己无法解决的问题。我认为当有Spring经验的人检查时,解决方案可能很明显。
我有一个非常简单的存储库:
interface MovieRepository extends Repository<Movie, Long> {
Movie findMovieById(Long id);
void save(Movie movie);
}
和Facade执行一些操作:
@AllArgsConstructor
public class MovieFacade {
private MovieRepository movieRepository;
private MovieCreator movieCreator;
public MovieDto getMovieById(Long id){
Optional<Movie> movie = Optional.ofNullable(movieRepository.findMovieById(id));
return movie.isPresent() ? movie.get().toDto() : null;
}
配置类如下所示:
@Configuration
class MovieConfiguration {
@Bean
MovieFacade movieFacade(MovieRepository repository, MovieCreator movieCreator){
return new MovieFacade(repository, movieCreator);
}
@Bean
MovieCreator movieCreator(){
return new MovieCreator();
}
我想创建一些测试,每次尝试运行它时都会失败:
@RunWith(SpringJUnit4ClassRunner.class)
public class MovieFacadeTest {
@Autowired
MovieFacade movieFacade;
@Test
public void dependecyWorks(){
assertNotNull(movieFacade);
}
这是我得到的错误:
org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为'com.example.demo.movie.domain.MovieFacadeTest'的bean时出错:通过字段'movieFacade'表示不满意的依赖关系;嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:没有'com.example.demo.movie.domain.MovieFacade'类型的限定bean可用:预计至少有1个bean可以作为autowire候选者。依赖注释:{@ org.springframework.beans.factory.annotation.Autowired(required = true)} 在org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:588) 在org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88) 在org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:366) 在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1264) 在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:386) at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:118) 在org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83) 在org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:230) 在org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:228) 在org.springframework.test.context.junit4.SpringJUnit4ClassRunner $ 1.runReflectiveCall(SpringJUnit4ClassRunner.java:287) 在org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 在org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:289) 在org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:247) 在org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94) 在org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:290) 在org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java:71) 在org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 在org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:58) 在org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:268) 在org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 在org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) 在org.junit.runners.ParentRunner.run(ParentRunner.java:363) 在org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191) 在org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:78) 在com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:212) 在com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在com.intellij.rt.execution.application.AppMain.main(AppMain.java:140) 引起:org.springframework.beans.factory.NoSuchBeanDefinitionException:没有'com.example.demo.movie.domain.MovieFacade'类型的限定bean可用:预计至少有1个bean可以作为autowire候选者。依赖注释:{@ org.springframework.beans.factory.annotation.Autowired(required = true)}
就我而言,对象movieFacade应该在MovieConfiguration中创建,然后在测试类中注入movieFacade。 由于某种原因,它根本不会发生。 我将不胜感激任何可能导致解决此问题的帮助或提示。
答案 0 :(得分:0)
仔细阅读堆栈跟踪说:
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.example.demo.movie.domain.MovieFacade' available: expected at least 1 bean which qualifies as autowire candidate.
您没有使用@Service或@Component注释您的MovieFacade,因此它不会被应用程序上下文拾取。此外,如果MovieFacade与配置类不在同一个包中,则应在配置上方使用@ComponentScan注释。 @ComponentScan()可以将包名和类名作为参数。如果MovieFacade与配置文件位于同一个包中,则不需要@ComponentScan,因为默认情况下配置类会扫描自己的包中的组件。
希望这有帮助。
编辑:此外,MovieRepository应该有注释@Repository
答案 1 :(得分:0)
我认为您需要使用@ContextConfiguration
注释您的测试类,并提供配置类的类引用。在运行JUNIT时,它不会自动创建已定义MovieFacade bean的Spring上下文。您需要在JUnit类中提供该引用。