必须使用mockbean而不是autowired

rob*_*del 1 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(){

    }

}
Run Code Online (Sandbox Code Playgroud)

我明白了

org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为'com.namur.service.VehicleServiceImplTest'的bean时出错:通过字段'repository'表示的不满意的依赖关系; 嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:没有'com.namur.repository.VehicleRepository'类型的限定bean可用:预期至少有1个bean可以作为autowire候选者.依赖注释:{@ org.springframework.beans.factory.annotation.Autowired(required = true)}在org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:586)

如果我用MockBean替换Autowired它正在工作,但我不知道为什么

dav*_*xxx 7

如果我用 MockBean 替换 Autowired 它可以工作,但我不知道为什么

它的工作原理,因为@MockBean内容替换或增加一个beanSpring上下文。
在您的情况下,它repository在 Spring 上下文中添加了一个模拟。
所以这不能抛出任何UnsatisfiedDependencyException.

但这不是您所需要的,因为您最初@Autowired使用的目的是上下文中注入 bean 。

@Autowired并且@MockBean确实是两种截然不同的东西,您永远无法替代相同的需求。


作为旁注,您可能应该重新考虑构建测试的方式。

实际上你正在使用SpringJUnit4ClassRunner跑步者。
这意味着您要使用 Spring 容器进行测试。
这是一种有效的方法。但是在这种情况下,为什么要在 Spring 容器之外创建 VehiculeServiceImpl 呢?

 service = new VehiculeServiceImpl(repository);
Run Code Online (Sandbox Code Playgroud)

您应该更愿意注入该服务。

请注意,在容器外创建被测类的新实例也是一种非常有效的方法。
我们在编写简单的单元测试时这样做。如果你想这样做,不要使用 Spring Boot runner,顺便说一下,这会使测试变慢。


Plo*_*log 5

这是因为你没有提供任何关于弹簧上下文的指示,因此没有可用于自动装配的豆子.

通过提供@MockBean,您实际上是使用单个现有bean提供测试上下文,该bean是VehicleRepository类的模型.

您可以使用@SpringBootTest注释来加载弹簧上下文,供您在测试中使用.那么你应该能够@Autowire实际的存储库:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class VehicleServiceImplTest {
Run Code Online (Sandbox Code Playgroud)