我正在尝试通过 mockito 模拟 restTemplate.exchange 方法,但无论我通过 mock 返回什么,它总是返回一个空值,即使我抛出异常:
这是实际代码:
ResponseEntity<List<LOV>> response = restTemplate.exchange(url, GET, null,new ParameterizedTypeReference<List<LOV>>() {});
莫米托代码:
ResponseEntity<List<LOV>> mockResponse = new ResponseEntity<List<LOV>>(mockLovList() ,HttpStatus.ACCEPTED);
Mockito.when(restTemplate.exchange(any(), eq(GET), any(), ArgumentMatchers.<ParameterizedTypeReference<List<LOV>>>any())).thenReturn(mockResponse);
每个参数在交换模拟中都是 ArgumentMatchers 的类型, mockLovList() 返回一个 LOV 列表
它应该返回我模拟的任何内容,但它总是返回 null
下面是一个RestTemplate.exchange()
模拟测试的工作示例:
import org.junit.Assert;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;
import java.util.Arrays;
import java.util.List;
import static org.mockito.Mockito.*;
public class MyTest {
@Test
public void testRestTemplateExchange() {
RestTemplate restTemplate = mock(RestTemplate.class);
HttpEntity<String> httpRequestEntity = new HttpEntity<>("someString");
List<String> list = Arrays.asList("1", "2");
ResponseEntity mockResponse = new ResponseEntity<>(list, HttpStatus.ACCEPTED);
when(restTemplate.exchange(anyString(), any(), any(), any(ParameterizedTypeReference.class), any(Object[].class)))
.thenReturn(mockResponse);
final ResponseEntity<List<String>> exchange = restTemplate.exchange("/someUrl", HttpMethod.GET, httpRequestEntity, new ParameterizedTypeReference<List<String>>() {
});
Assert.assertEquals(list, exchange.getBody());
}
}
您需要确保在设置或注入服务之前初始化模拟。喜欢这个-
@Mock
RestTemplate restTemplate;
@Before
public void init() {
MockitoAnnotations.initMocks(this);
userData = new UserService(restTemplate);
}
怎么样:
when(restTemplate.exchange(anyString(), any(), any(),
eq(new ParameterizedTypeReference<List<LOV>>() {})))
.thenReturn(responseEntity);
如果您使用:
when(restTemplate.exchange(anyString(), any(), any(),
any(ParameterizedTypeReference.class)))
.thenReturn(responseEntity);
你遇到Unchecked assignment
.您也不需要第 5 个参数。
首先,您可以使用以下命令验证方法调用是否正确
Mockito.verify(restTemplate).exchange(any(), eq(GET), any(), any(ParameterizedTypeReference.class)))
Mockito展示了一个非常好的输出,包括实际的方法调用。
此外,您可以参考深度存根或测试匿名类
我遇到了同样的问题(至少 2 个涉及这个问题),在寻找一个合理的答案后,我可以成功修复它。
在我解释之前,我将分享 2 个对我有帮助的解释。如何模拟 REST 模板交换?和 Mocking RestTemplate.exchange() 方法给出空值。
所以,基本上,关键是每个涉及任何 RestTemplate 方法的测试用例都必须正确给出每个参数。如果它不正常,那么 Mockito 会失败并抛出如下异常:
org.mockito.exceptions.misusing.PotentialStubbingProblem
或者使用 NullPointerException 从 restTemplate.exchange 获取 ResponseEntity(这是您的情况)
之前(我隐藏了一些实现。莫基托抛出了一个例外)
when(restTemplate.exchange(anyString(), any(HttpMethod.class), any(),
ArgumentMatchers.<ParameterizedTypeReference<FilterBean>>any())).thenReturn(responseEntityFilterBean);
莫基托例外
org.mockito.exceptions.misusing.PotentialStubbingProblem: Strict 存根参数不匹配。请检查:
- "交换"方法的调用: restTemplate.exchange( "/过滤器", 获取 <[内容类型:"应用程序/json"]>, 类 br.com.test.bean.FilterBean ); -> at br.com.test.service.FilterService.getFilterStatus(FiltroService.java:60)
具有- 以下具有不同参数的存根:
- restTemplate.exchange(">
, null, null, null);
这表明争论是不行的!
更改我的代码它解决了我的问题。
when(restTemplate.exchange(ArgumentMatchers.anyString(),
ArgumentMatchers.any(HttpMethod.class),
ArgumentMatchers.any(),
ArgumentMatchers.<Class<FilterBean>>any())).thenReturn(responseEntityFilterBean);
在您的情况下,请尝试这样做,它将解决:
when(restTemplate.exchange(ArgumentMatchers.anyString(),
ArgumentMatchers.any(HttpMethod.class),
ArgumentMatchers.any(), ArgumentMatchers.<Class<List<String>>>any())))
.thenReturn(mockResponse);
由于类型不匹配,我遇到了此错误,我的网址是URI而不是字符串。这就是对我有用的东西。
when(restTemplate.exchange(
ArgumentMatchers.any(URI.class),
ArgumentMatchers.any(HttpMethod.class),
ArgumentMatchers.any(),
ArgumentMatchers.eq(String.class)
)).thenReturn(mockResponse);
请注意,我的项目使用的是字符串.class而不是参数化类型引用
public class EmployeeServiceTest {
@Mock
private RestTemplate restTemplate;
// Instiantiating the service is important, otherwise resttempate null pointer error is thrown.
@InjectMocks
private EmployeeService empService = new EmployeeService();
@Test
public void givenMockingIsDoneByMockito_whenGetIsCalled_shouldReturnMockedObject() {
Employee emp = new Employee(“E001”, "Eric Simmons");
Mockito
.when(restTemplate.getForEntity(
“http://localhost:8080/employee/E001”, Employee.class))
.thenReturn(new ResponseEntity(emp, HttpStatus.OK));
Employee employee = empService.getEmployee(id);
Assertions.assertEquals(emp, employee);
}
}