Spring Boot如何在src / test中定义@Components,以便它们可以@Autowire进入测试?

时间:2018-11-16 23:47:29

标签: spring unit-testing spring-boot integration-testing

我正在尝试进行REST api的集成测试。我已经编写了一些测试实用程序类来构建测试数据,我想将它们@Autowire放入我的测试方法中。运行测试时,@Autowire失败,因为Spring不了解这些组件。我开始在测试中添加内部@Configuration类,但是我尝试将@Autowire存储库添加到这些实用程序中,因此我需要@Autowire链才能工作。能做到吗?我该怎么办?

@RunWith(SpringRunner.class)
@SpringBootTest
@TestPropertySource(locations = "classpath:application-it.properties")
public class ContactControllerIT
{
    @Autowired
    private ContactController contactController;   // <---  This autowires as expected

    @Autowired
    private TestContactBuilder contactBuilder;    // <--- This class is defined in src/test and autowired fail w/ no bean found error

示例项目:https://github.com/tbbstny/spring-boot-it-study

2 个答案:

答案 0 :(得分:0)

如果要测试控制器,则不需要在测试中使用它。您将使用MockMvc

以下是示例:

@RunWith(SpringRunner.class)
@AutoConfigureMockMvc
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@EnableAutoConfiguration
public class SomeTest {

 @Autowired
 private MockMvc mockMvc;

 @Test
 public void getGeneratedPassword_shouldReturn200Status() throws Exception {
 boolean isGenerated = this.mockMvc.perform(get("/generate/password/1").with(httpBasic(this.username, this.password)))
        .andExpect(authenticated())
        .andExpect(status().isOk())
        .andReturn()
        .getResponse()
        .getContentAsString().isEmpty;

 assertFalse(isGenerated);
  }    
}

测试将通过,因为它将返回非空字符串。还有两个验证阶段。如果用户正确,并且HTTP状态为200。

它可以在2.1.0 Spring Boot及更高版本中使用。您还可以添加application.properties路径。

文档:https://spring.io/guides/gs/testing-web/

当前代码中可以使用的另一个方法是添加此注释:

@SpringBootTest(classes = {ContactController.class, TestContactBuilder.class})

答案 1 :(得分:0)

确定这不是要扫描src / test / java的问题,而是对Spring Boot的默认扫描过程的理解。我将数据构建器组件添加到了一个不同于@SpringBootApplication注释的包中。默认情况下,Spring将对该组件以及该组件中嵌套的所有组件进行组件扫描。有两种方法可以解决我的问题:

  1. 将数据构建工具移动到与@SpringBootApplication相同的程序包中,即com.ttt.example.api
  2. 添加@ComponentScan 到Application类以包括数据构建器的包 utils已加入。

    @ComponentScan("com.ttt.example")  // <-- Move up to root package to ensure all my components are scanned
    @SpringBootApplication
    public class Application