我尝试使用@RestController
在集成测试套件中测试MockMvc
。
@RunWith(SpringRunner.class)
@SpringBootTest
@WebAppConfiguration
public class WebControllerIT {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
}
@Test
public void getStatusReurnsSomething() throws Exception {
this.mockMvc.perform(get("/status")).andExpect(status().isOk());
}
}
@RestController
(WebController
)调用注入的@Service
(RestClientService
),它使用RestTemplate
来调用另一个REST服务器。运行测试时会出现以下错误。
org.springframework.web.client.ResourceAccessException:I / O错误 GET请求" http://test123.com/42/status":test123.com;嵌套 异常是java.net.UnknownHostException:test123.com
我使用MockRestServiceServer
进行@Service
本身的集成测试,但不知道如何在@RestController
的测试中实现此目的。
如何模拟RestTemplate
的正确REST调用?
@RestController
班。
@RestController
public class WebController {
private final RestClientService service;
@Autowired
public WebController(RestClientService service) {this.service = service;}
@GetMapping("/status")
public String getStatus() {
// extract pid from database ...
int pid = 42;
return this.service.getStatus(42);
}
}
@Service
班。
@Service
public class RestClientService {
private final RestTemplate restTemplate;
public RestClientService(RestTemplate restTemplate) {this.restTemplate = restTemplate;}
public String getStatus(int pid) {
String url = String.format("http://test123.com/%d/status", pid);
return this.restTemplate.getForObject(url, String.class);
}
}
答案 0 :(得分:2)
集成/单元测试不起作用。这种测试的目的是贯穿你的代码,确保满足所有的业务需求,但不要打到其他系统或DB。在你的情况下,你应该要点击test123.com来获取数据。这里需要做的是你应该模仿那个方法。
public String getStatus(int pid) {
String url = String.format("http://test123.com/%d/status", pid);
return this.restTemplate.getForObject(url, String.class);
}
因此控件不会进入此方法,但会返回模拟数据(虚拟数据)。
例如,假设此方法返回有两种状态,您需要根据返回的字符串进行一些业务验证。在这种情况下,您需要编写2个集成测试并确保模拟方法返回2不同的值(虚拟值而不是命中该终点)
我们编写单元测试/集成测试的原因是为了确保您的整个代码按预期工作,而不是从您的代码中打到其他系统。
答案 1 :(得分:1)
如果你只想测试你的控制器层,你会这样做。
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MockServletContext.class)
@WebAppConfiguration
public class WebControllerIT {
private MockMvc mockMvc;
private RestClientService service
@Mock
private RestTemplate restTemplate
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
service = new RestClientService(restTemplate);
WebController webController = new WebController(service);
mvc = MockMvcBuilders.standaloneSetup(webController).build();
}
@Test
public void getStatusReurnsSomething() throws Exception {
//Mock the behaviour of restTemplate.
doReturn("someString").when(restTemplate).getForObject(anyString(), anyString());
this.mockMvc.perform(get("/status")).andExpect(status().isOk());
}
}