首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >@webMvcTest不排除并加载标记为@Repository的beans

@webMvcTest不排除并加载标记为@Repository的beans
EN

Stack Overflow用户
提问于 2020-10-27 00:16:13
回答 3查看 990关注 0票数 1

我有一个在@Autowire字段中只有一个依赖项的组件,这个依赖项是@ @RestController,组件类定义有一些自动连接的字段是@@Autowire,这些服务有一些@repositories。

在整个流程中,我使用了kafka、Quartz、Cassandra和DB2,所以当我为控制器创建单元测试用例时,我不想设置整个应用程序。因此,我决定使用@webMvcTest,并在我唯一的一个控制器类依赖项上使用@MockBean。

但是我的测试抛出了异常,因为它试图创建一个Dao bean,它被标记为@repository。

代码语言:javascript
运行
复制
@ActiveProfiles("test")
@WebMvcTest(controllers = MyControllerTest .class)
class MyControllerTest {

    @MockBean
    MyControllerDependency dependency;

    @Autowired
    MockMvc mockMvc;

    @Test
    void test_something() throws Exception {
       assert(true);
    }
}

以下是代码的简化版本

代码语言:javascript
运行
复制
@Component
class MyControllerDependency { 
    @AutoiWired
    MyCustomService service;
}

@Service
class MyCustomService{

   @Autowired
   MyCustomDao dao;
}

@Repository
class MyCustomDao{
    @Autowired
    private JdbcTemplate template;
}

我在测试中遇到了下面的异常。

代码语言:javascript
运行
复制
Exception

***************************
APPLICATION FAILED TO START
***************************

Description:

Field template in com.....MyCustomDao`  required a bean of type 'org.springframework.jdbc.core.JdbcTemplate' that could not be found.

问题是,当我使用@WebMvcTest slice并且已经模拟了唯一需要的依赖MyControllerDependency时,为什么spring测试上下文要尝试加载被注释为@RepositoryMyCustomDao

我可以使用SpringbootTestAutoconfigureMockMVC进行集成测试,但是为了编写仅用于控制器的Junit测试,我需要使用WebMvcTest slice。这就产生了一个问题。

EN

回答 3

Stack Overflow用户

发布于 2020-10-27 02:29:44

这通常发生在spring boot主应用程序类上有显式的@ComponentScan注释时。

@ComponentScan注释抑制了发生在@Webmvctest中的默认组件扫描机制,在该机制中,它向上扫描包层次结构,并应用excludeFilters来仅查找控制器及其相关类。

票数 2
EN

Stack Overflow用户

发布于 2021-06-08 16:41:27

我遇到了一个类似的问题,我只想使用@WebMvcTest测试我的控制器,但spring上下文试图创建非依赖的spring bean,并失败了,如下所示。

无法加载bean :无法加载bean,原因是: org.springframework.beans.factory.UnsatisfiedDependencyException:在创建文件中定义的名为'TestController‘的ApplicationContext时出错...

解决方案:仅加载您的测试中的控制器,例如@ContextConfiguration(classes = DemoController.class)。此外,还可以在下面找到完整的示例

代码语言:javascript
运行
复制
@WebMvcTest
@ContextConfiguration(classes = DemoController.class)  
public class DemoControllerTest {    
@Autowired
MockMvc mockMvc;

@MockBean
DemoService demoService;

@Test
public void testGetAllProductCodes_withOutData() throws Exception {
    
when(productCodeService.getAllProductCodes()).thenReturn(new ArrayList<ProductCodes>());
        mockMvc.perform(MockMvcRequestBuilders.get("/services/productCodes")).andExpect(MockMvcResultMatchers.status().isNoContent());
    }
}

}

票数 2
EN

Stack Overflow用户

发布于 2020-10-27 01:54:02

当你使用@MockBean注解模拟你的bean时,你应该定义当你调用它的方法时,被模拟的bean应该做什么,你通常在Mockito中使用when来做这件事。在您的情况下,可以这样做:

代码语言:javascript
运行
复制
@ActiveProfiles("test")
@WebMvcTest
class MyControllerTest {

    @MockBean
    MyControllerDependency dependency;

    @Autowired
    MockMvc mockMvc;

    @Test
    void test_something() throws Exception {
        when(dependency.sample()).thenReturn("Hello, Mock");
        mockMvc.perform(get("/api/test/restpoint")
                .accept(MediaType.APPLICATION_JSON))
               .andDo(print())
               .andExpect(status().isOk());
    }
}

在这一行中:

代码语言:javascript
运行
复制
when(dependency.sample()).thenReturn("Hello, Mock");

当您将MyControllerDependency请求发送到/api/test/restpoint路径时,您应该将控制器调用的GET类的任何方法放入/api/test/restpoint,而不是/api/test/restpoint,并使用thenReturn("Hello, Mock")定义该方法的模拟输出(当它被您的控制器在单元测试中调用时)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64540972

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档