如何使用 MockRestServiceServer 模拟 RestTemplate?
How to mock RestTemplate with MockRestServiceServer?
@RunWith(MockitoJUnitRunner.class)
public class FeatureFlipperManagerTest {
@Autowired
RestTemplate restTemplate = new RestTemplate();
@Autowired
Service service = new Service();
MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate);
@Test
public void test() throws Exception {
mockServer.expect(requestTo(Mockito.anyString()))
.andRespond(withSuccess("{\"enabled\":true}", MediaType.APPLICATION_JSON));
boolean res = service.isEnabled("xxx");
mockServer.verify();
Assert.assertEquals(true, res);
}
}
我有 MockRestServiceServer 来模拟服务中的 restTemplete。但它总是失败。它将错误显示为 java.lang.AssertionError: Further request(s) expected
0 out of 1 were executed
。任何人都可以让我知道我哪里做得不对。
服务本身将如下所示:
public class Service{
public boolean isEnabled(String xxx) {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.getForEntity("someurl",String.class);
if(...)return true;
return false;
}
}
首先,您的 Service
class 在每次请求时都会创建一个新的 RestTemplate 实例。我怎么强调这是多么糟糕的做法。创建一个类型为 RestTemplate 的 bean 并将其注入您的 Service
bean(它很可能已经创建 - 取决于您使用的 Spring MVC 版本)。
一旦你拥有它,那么两个 RestTemplates:一个在你的 Service
bean 中,一个注入到 FeatureFlipperManagerTest
中将是相同的,并且可以使用 MockRestServiceServer
进行测试。
编辑 - 更明确地说:
将您的 Service
class 修改为:
@Component
public class Service {
private RestTemplate restTemplate;
@Autowired
public Service(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
public boolean isEnabled(String xxx) {
ResponseEntity<String> response = restTemplate.getForEntity("someurl",String.class);
if(...)return true;
return false;
}
}
你的测试 class 到:
@RunWith(MockitoJUnitRunner.class)
public class FeatureFlipperManagerTest {
@Autowired
RestTemplate restTemplate;
@Autowired
Service service;
MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate);
@Test
public void test() throws Exception {
mockServer.expect(requestTo(Mockito.anyString()))
.andRespond(withSuccess("{\"enabled\":true}", MediaType.APPLICATION_JSON));
boolean res = service.isEnabled("xxx");
mockServer.verify();
Assert.assertEquals(true, res);
}
}
如果此操作失败并显示不存在 RestTemplate
bean,请粘贴有关您正在使用的 Spring(Spring Boot?)版本的信息。
我想你的意思是你想使用 spring 提供的 RestTemplate,所以你应该在 spring 自动装配 RestTemplate 之后创建服务器。我想你可以这样做:
@RunWith(MockitoJUnitRunner.class)
public class FeatureFlipperManagerTest {
@Autowired
RestTemplate restTemplate;
Service service;
MockRestServiceServer mockServer;
@Before
public void init() {
service = new Service();
service.setRestTemplate(restTemplate);
// If you have autowired restTemplate in Service, you can just autowired the service
mockServer = MockRestServiceServer.createServer(restTemplate);
}
@Test
public void test() throws Exception {
mockServer.expect(requestTo(Mockito.anyString()))
.andRespond(withSuccess("{\"enabled\":true}", MediaType.APPLICATION_JSON));
boolean res = service.isEnabled("xxx");
mockServer.verify();
Assert.assertEquals(true, res);
}
}
这不是您问题的答案,但以防万一有人在 2021 年遇到这个问题……使用 Spring 启动测试,您可能只想使用 [= 测试 REST 切片11=]。默认情况下,这只会创建一个 RestTemplateBuilder
bean,如果你想要一个自动连接的 RestTemplate
只需添加一点配置,如下所示。 (这个例子是在 Kotlin 中,使用 Java 而不是 reader 的练习。)
@AutoConfigureWebClient(registerRestTemplate = true)
@RestClientTest(Service::class)
class AdkClientTest @Autowired constructor(
private val mockRestServiceServer: MockRestServiceServer,
private val service: Service
) {
// …
}
@RunWith(MockitoJUnitRunner.class)
public class FeatureFlipperManagerTest {
@Autowired
RestTemplate restTemplate = new RestTemplate();
@Autowired
Service service = new Service();
MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate);
@Test
public void test() throws Exception {
mockServer.expect(requestTo(Mockito.anyString()))
.andRespond(withSuccess("{\"enabled\":true}", MediaType.APPLICATION_JSON));
boolean res = service.isEnabled("xxx");
mockServer.verify();
Assert.assertEquals(true, res);
}
}
我有 MockRestServiceServer 来模拟服务中的 restTemplete。但它总是失败。它将错误显示为 java.lang.AssertionError: Further request(s) expected
0 out of 1 were executed
。任何人都可以让我知道我哪里做得不对。
服务本身将如下所示:
public class Service{
public boolean isEnabled(String xxx) {
RestTemplate restTemplate = new RestTemplate();
ResponseEntity<String> response = restTemplate.getForEntity("someurl",String.class);
if(...)return true;
return false;
}
}
首先,您的 Service
class 在每次请求时都会创建一个新的 RestTemplate 实例。我怎么强调这是多么糟糕的做法。创建一个类型为 RestTemplate 的 bean 并将其注入您的 Service
bean(它很可能已经创建 - 取决于您使用的 Spring MVC 版本)。
一旦你拥有它,那么两个 RestTemplates:一个在你的 Service
bean 中,一个注入到 FeatureFlipperManagerTest
中将是相同的,并且可以使用 MockRestServiceServer
进行测试。
编辑 - 更明确地说:
将您的 Service
class 修改为:
@Component
public class Service {
private RestTemplate restTemplate;
@Autowired
public Service(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
public boolean isEnabled(String xxx) {
ResponseEntity<String> response = restTemplate.getForEntity("someurl",String.class);
if(...)return true;
return false;
}
}
你的测试 class 到:
@RunWith(MockitoJUnitRunner.class)
public class FeatureFlipperManagerTest {
@Autowired
RestTemplate restTemplate;
@Autowired
Service service;
MockRestServiceServer mockServer = MockRestServiceServer.createServer(restTemplate);
@Test
public void test() throws Exception {
mockServer.expect(requestTo(Mockito.anyString()))
.andRespond(withSuccess("{\"enabled\":true}", MediaType.APPLICATION_JSON));
boolean res = service.isEnabled("xxx");
mockServer.verify();
Assert.assertEquals(true, res);
}
}
如果此操作失败并显示不存在 RestTemplate
bean,请粘贴有关您正在使用的 Spring(Spring Boot?)版本的信息。
我想你的意思是你想使用 spring 提供的 RestTemplate,所以你应该在 spring 自动装配 RestTemplate 之后创建服务器。我想你可以这样做:
@RunWith(MockitoJUnitRunner.class)
public class FeatureFlipperManagerTest {
@Autowired
RestTemplate restTemplate;
Service service;
MockRestServiceServer mockServer;
@Before
public void init() {
service = new Service();
service.setRestTemplate(restTemplate);
// If you have autowired restTemplate in Service, you can just autowired the service
mockServer = MockRestServiceServer.createServer(restTemplate);
}
@Test
public void test() throws Exception {
mockServer.expect(requestTo(Mockito.anyString()))
.andRespond(withSuccess("{\"enabled\":true}", MediaType.APPLICATION_JSON));
boolean res = service.isEnabled("xxx");
mockServer.verify();
Assert.assertEquals(true, res);
}
}
这不是您问题的答案,但以防万一有人在 2021 年遇到这个问题……使用 Spring 启动测试,您可能只想使用 [= 测试 REST 切片11=]。默认情况下,这只会创建一个 RestTemplateBuilder
bean,如果你想要一个自动连接的 RestTemplate
只需添加一点配置,如下所示。 (这个例子是在 Kotlin 中,使用 Java 而不是 reader 的练习。)
@AutoConfigureWebClient(registerRestTemplate = true)
@RestClientTest(Service::class)
class AdkClientTest @Autowired constructor(
private val mockRestServiceServer: MockRestServiceServer,
private val service: Service
) {
// …
}