我想写一个测试控制器。下面是测试片段:
@RunWith(SpringRunner.class)
@WebMvcTest(WeatherStationController.class)
@ContextConfiguration(classes = MockConfig.class)
public class WeatherStationControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private IStationRepository stationRepository;
@Test
public void shouldReturnCorrectStation() throws Exception {
mockMvc.perform(get("/stations")
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
}
}
控制器代码片段:
@RestController
@RequestMapping(value = "stations")
public class WeatherStationController {
@Autowired
private WeatherStationService weatherService;
@RequestMapping(method = RequestMethod.GET)
public List<WeatherStation> getAllWeatherStations() {
return weatherService.getAllStations();
}
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public WeatherStation getWeatherStation(@PathVariable String id) {
return weatherService.getStation(id);
}
模拟配置类:
@Configuration
@ComponentScan(basePackages = "edu.lelyak.repository")
public class MockConfig {
//****************************MOCK BEANS******************************
@Bean
@Primary
public WeatherStationService weatherServiceMock() {
WeatherStationService mock = Mockito.mock(WeatherStationService.class);
return mock;
}
以下是错误堆栈跟踪:
java.lang.AssertionError: Status
Expected :200
Actual :404
我能理解这里的问题。
如何修复控制器的测试?
9条答案
按热度按时间xdnvmnnf1#
HTTP code 404,意味着没有找到资源(在服务器上)为您的请求,我认为您的控制器是不可见的(让我说是没有扫描)由Spring Boot .
一个简单的解决方案是扫描
MockConfig
类中的父包,这样Spring就可以拾取所有bean,如果您不喜欢这种方法,您可以在
basePackages
中添加控制器的软件包名称顺便说一句,你不必在
MockConfig
类中手动设置WeatherStationService
,Spring boot可以为你注入一个mock,并在每个测试方法后自动重置它,你只需在你的测试类中声明它:另一方面,在测试方法中调用
get("/stations")
之前,您应该模拟weatherService.getAllStations()
(因为您没有运行integration test),这样您就可以:您可以在以下位置找到更多信息:
xqk2d5yq2#
我遇到了同样的问题。尽管用
@WebMvcTest(MyController.class)
指定了控制器,但控制器没有被选中。这意味着它的所有Map都被忽略了,导致404。添加@Import(MyController.class)
解决了这个问题,但我不认为在我已经指定要测试的控制器时,导入是必要的。brvekthn3#
我不知道为什么你的测试不起作用。但我有另一个解决方案对我有效。
uplii1fm4#
经过一些调试后,目标控制器似乎只是没有注册为方法处理程序。Spring扫描bean,看是否存在
RestController
注解。但问题是,只有通过CGLIB代理bean时才能找到注解,但对于使用
WebMvcTest
的情况,它是通过JDK代理的。因此,我搜索了负责做出选择的配置,最终找到了
AopAutoConfiguration
。因此,当使用SpringBootTest时,当您需要在控制器中使用WebMvcTest+PreAuthorize
时,此配置会自动加载,然后只需用途:lyr7nygr5#
我通过
@ContextConfiguration(classes = MyConfig.class)
导入外部配置类当我将
MyConfig
注解@Configuration
更改为@TestConfiguration
时,它开始正常工作。tag5nh1u6#
我找不到一个好的答案,但我能找到其中的一个原因。
我在测试中使用的是RestController上的
@PreAuthorize
。您可以在使用
SpringBootTest
的集成测试上使用this tip模拟Oauth。对于SpringBootTest
,这也非常有效,但是使用SpringBootTest
,您会加载许多其他资源(如JPA),这些资源对于执行简单的Controller测试是不必要的。但是对于
@WebMvcTest
,这并不像预期的那样工作。使用WithMockOAuth2Scope注解足以阻止来自身份验证问题的401错误,但是在那之后WebMvcTest找不到其余的端点,返回404错误代码。移除控制器上的
@PreAuthorize
后,WebMvcTest
的测试通过。eblbsuwk7#
基于accepted answer,在我的例子中,我已经根据另一个测试复制和修改了文件,但是忘记了更改类顶部的控制器的名称,这就是为什么它没有找到资源的原因,正如错误所说的那样。
avwztpqn8#
下面是一种不同的控制器测试方法,它对我很有效。
假设:类
WeatherStationService
是@SpringBootApplication
然后,下面的测试类应该对您有效:
使用此测试设置,您应该不再需要
MockConfig
类。u7up0aaq9#
在我的例子中,它是关于一个缺少的开始斜杠
/
我已将
/
作为第一个字符附加到RequestMapping value
和MockHttpServletRequestBuilder post urlTemplate
参数。