我使用spring boot 2
我创建了一个基本测试
@RunWith(SpringJUnit4ClassRunner.class)
public class VehicleServiceImplTest {
private VehiculeServiceImpl service;
@Autowired
private VehicleRepository repository;
@Before
public void prepare() {
service = new VehiculeServiceImpl(repository);
}
@Test
public void test(){
}
}
我得到了
org.springframework.beans.factory.UnsatisfiedDependencyException: 使用名称创建bean时出错 'com.namur.service.VehicleServiceImplTest':不满意的依赖 通过字段'存储库'表示;嵌套异常是 org.springframework.beans.factory.NoSuchBeanDefinitionException:没有 'com.namur.repository.VehicleRepository'类型的限定bean 可用:预计至少有1个符合autowire资格的bean 候选人。依赖注释: {@ org.springframework.beans.factory.annotation.Autowired(所需=真)} 在 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:586)
如果我用MockBean替换Autowired它正在工作,但我不知道为什么
答案 0 :(得分:5)
这是因为你没有提供任何关于弹簧背景的指示,因此根本没有可用于自动装配的豆。
通过提供@MockBean,您实际上是使用单个现有bean提供测试上下文,该bean是VehicleRepository类的模拟。
您可以使用@SpringBootTest注释来加载弹簧上下文,供您在测试中使用。那么你应该能够@Autowire实际的存储库:
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class VehicleServiceImplTest {
答案 1 :(得分:3)
如果我用MockBean取代Autowired它可以正常工作,但我不知道为什么
它的工作原理是因为@MockBean
取代了将添加一个bean 加入 Spring上下文。
在您的情况下,它在Spring上下文中添加了repository
模拟
所以这不能抛出任何UnsatisfiedDependencyException
。
但是,您最初使用的@Autowired
用于从上下文中注入bean ,这不是必需的。
@Autowired
和@MockBean
确实是两个非常不同的东西,你永远无法替代同样的需求。
作为旁注,您应该重新考虑测试的构建方式。
实际上你正在使用SpringJUnit4ClassRunner
亚军
这意味着您要使用Spring容器进行测试
这是一种有效的方法。但在这种情况下,为什么要在Spring容器外创建VehiculeServiceImpl?
service = new VehiculeServiceImpl(repository);
你应该注入服务。
请注意,在容器外部创建测试类的新实例也是一种非常有效的方法 我们在编写普通单元测试时这样做。如果你想这样做,不要使用Spring Boot运行器,顺便说一下,它会使测试更慢。