我有一个在@Autowire
字段中只有一个依赖项的组件,这个依赖项是@ @RestController
,组件类定义有一些自动连接的字段是@@Autowire
,这些服务有一些@repositories。
在整个流程中,我使用了kafka、Quartz、Cassandra和DB2,所以当我为控制器创建单元测试用例时,我不想设置整个应用程序。因此,我决定使用@webMvcTest,并在我唯一的一个控制器类依赖项上使用@MockBean。
但是我的测试抛出了异常,因为它试图创建一个Dao bean,它被标记为@repository。
@ActiveProfiles("test")
@WebMvcTest(controllers = MyControllerTest .class)
class MyControllerTest {
@MockBean
MyControllerDependency dependency;
@Autowired
MockMvc mockMvc;
@Test
void test_something() throws Exception {
assert(true);
}
}
以下是代码的简化版本
@Component
class MyControllerDependency {
@AutoiWired
MyCustomService service;
}
@Service
class MyCustomService{
@Autowired
MyCustomDao dao;
}
@Repository
class MyCustomDao{
@Autowired
private JdbcTemplate template;
}
我在测试中遇到了下面的异常。
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测试上下文要尝试加载被注释为@Repository
的MyCustomDao
。
我可以使用SpringbootTest
和AutoconfigureMockMVC
进行集成测试,但是为了编写仅用于控制器的Junit测试,我需要使用WebMvcTest
slice。这就产生了一个问题。
发布于 2020-10-27 02:29:44
这通常发生在spring boot主应用程序类上有显式的@ComponentScan注释时。
@ComponentScan注释抑制了发生在@Webmvctest中的默认组件扫描机制,在该机制中,它向上扫描包层次结构,并应用excludeFilters来仅查找控制器及其相关类。
发布于 2021-06-08 16:41:27
我遇到了一个类似的问题,我只想使用@WebMvcTest测试我的控制器,但spring上下文试图创建非依赖的spring bean,并失败了,如下所示。
无法加载bean :无法加载bean,原因是: org.springframework.beans.factory.UnsatisfiedDependencyException:在创建文件中定义的名为'TestController‘的ApplicationContext时出错...
解决方案:仅加载您的测试中的控制器,例如@ContextConfiguration(classes = DemoController.class)
。此外,还可以在下面找到完整的示例
@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());
}
}
}
发布于 2020-10-27 01:54:02
当你使用@MockBean
注解模拟你的bean时,你应该定义当你调用它的方法时,被模拟的bean应该做什么,你通常在Mockito中使用when
来做这件事。在您的情况下,可以这样做:
@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());
}
}
在这一行中:
when(dependency.sample()).thenReturn("Hello, Mock");
当您将MyControllerDependency
请求发送到/api/test/restpoint
路径时,您应该将控制器调用的GET
类的任何方法放入/api/test/restpoint
,而不是/api/test/restpoint
,并使用thenReturn("Hello, Mock")
定义该方法的模拟输出(当它被您的控制器在单元测试中调用时)。
https://stackoverflow.com/questions/64540972
复制相似问题