我对Mockito还是陌生的,需要一些帮助,可能是一些有关如何模拟Rest Template的getForEntity和postForEntity方法的示例。下面是我要通过模拟getForEntity方法编写Junit测试用例的代码。
SomeService.java
class SomeService
{
//some private, static, final data members
public Map getService(String sNo, String uId, String en)
{
ResponseEntity <Map> response = new
RestTemplate().getForEntity("https://someurl.com/someService",
Map.class);
Map body = response.getBody();
//do something
HttpEntity<?> request = new HttpEntity <>(payLoad, headers);
//payload is Hash Map and headers is a LinkedMultiValueMap
ResponseEntity <Map> response = new RestTemplate().postForEntity(url,
request, headers);
return response.getBody();
}
}
我尝试使用@Mock和@InjectMocks进行操作。
TestSomeService.java
@RunWith(MockitoJunitRunner.class)
class TestSomeService
{
@Mock
RestTemplate restTemplate;
@InjectMocks
SomeService ser;
/*Some data members*/
@Before
{
HttpEntity <?> request = new HttpEntity<>(reqPayload, headers);
Mockito.when(restTemplate.getForEntity("theUrl",
Map.class)).thenReturn(new ResponseEntity <Map>(someMap,
HttpStatus.OK));
Mockito.when(restTemplate.postForEntity("anotherUrl", request,
Map.class)).thenReturn(new ResponseEntity <Map>(expectedMap,
HttpStatus.OK));
}
@Test
public void testGetService()
{
Map <String, Object> result = ser.getService("123", "abc", "QA");
}
}
答案 0 :(得分:1)
调用特定值时,必须用ArgumentMatchers.eq()
包装。但是,您也可以使用anyString()
,any(Class class)
和其他名称。他们都是不言自明的。 Mockito tutorial。
@Before
public void init (){
MockitoAnnotations.initMocks(this);
HttpEntity <?> request = new HttpEntity<>(reqPayload, headers);
Mockito.when(restTemplate.getForEntity(ArgumentMatchers.eq("theUrl"),ArgumentMatchers.any(Map.class)))
.thenReturn(new ResponseEntity <Map>(someMap, HttpStatus.OK));
}
关于您的结构。通过这种方式,您可以通过构造函数注入RestTemplate
。
public class ServiceTester {
@Mock
private RestTemplate restTemplate;
private Service service;
@Before
public void init (){
MockitoAnnotations.initMocks(this);
service = new Service(restTemplate);
HttpEntity <?> request = new HttpEntity<>(reqPayload, headers);
Mockito.when(restTemplate.getForEntity(ArgumentMatchers.eq("theUrl"),ArgumentMatchers.any(Map.class)))
.thenReturn(new ResponseEntity <Map>(someMap, HttpStatus.OK));
}
}
class Service {
private RestTemplate template;
@Autowired
public Service(RestTemplate template) {
this.template = template;
}
public Map doSomething () {
// do something with template
}
}
答案 1 :(得分:0)
我像这样模拟一个休息模板
@RunWith(SpringRunner.class)
public class Clazz {
@Mock
private RestTemplate restTemplate;
}
因此,请尝试使用SpringRunner而不是MockitoRunner
答案 2 :(得分:0)
如果您被授权对SomeService类进行更改,建议您执行以下操作。
class SomeService
{
//some private, static, final data members
public Map getService(String sNo, String uId, String en)
{
ResponseEntity <Map> response = getForEntity("https://someurl.com/someService", Map.class);
Map body = response.getBody();
//do something
HttpEntity<?> request = new HttpEntity <>(payLoad, headers);
//payload is Hash Map and headers is a LinkedMultiValueMap
ResponseEntity <Map> response = postForEntity(url, request, headers);
return response.getBody();
}
}
您可能已经猜到getForEntity
和postForEntity
方法已被提取出来,并且RestTemplate实例化在其中-秘密地进行了工作。而且由于您从一开始就想模拟RestTemplate,所以我们摆脱了它是一件好事–现在我们可以监视我们的服务而无需模拟任何对象。
@RunWith(MockitoJunitRunner.class)
class TestSomeService
{
@InjectMocks
@Spy
SomeService ser;
/*Some data members*/
@Before
{
HttpEntity <?> request = new HttpEntity<>(reqPayload, headers);
doReturn(new ResponseEntity <Map>(someMap, HttpStatus.OK))
.when(ser).getForEntity("theUrl", Map.class));
doReturn(new ResponseEntity <Map>(expectedMap, HttpStatus.OK))
.when(ser).postForEntity("anotherUrl", request, Map.class));
}
@Test
public void testGetService()
{
Map <String, Object> result = ser.getService("123", "abc", "QA");
}
}
答案 3 :(得分:0)
您必须注入RestTemplate
服务SomeService
。当前,您正在服务中创建一个新实例。这意味着,您不会得到RestTemplate
的模拟实例,但是会得到真实类RestTemplate
的全新实例。
您必须执行以下操作:
class SomeService
{
@Inject
private RestTemplate restTemplate;
//some private, static, final data members
public Map getService(String sNo, String uId, String en)
{
ResponseEntity <Map> response = restTEmplate.getForEntity("https://someurl.com/someService",
Map.class);
...
}
}
答案 4 :(得分:0)
您确定要模拟一个restTemplate吗?
不模拟剩余模板而是模拟答案呢?
它还将帮助您测试restTemplate行为。如果restTemplate得到404或500怎么办?
这就是为什么我建议您使用MockRestServiceServer
它有助于检查所有现实情况。