必须使用mockbean而不是autowired

时间:2018-01-29 14:31:18

标签: spring-boot junit

我使用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它正在工作,但我不知道为什么

2 个答案:

答案 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运行器,顺便说一下,它会使测试更慢。