我如何模拟 Rest Template 的 getForEntity() 方法

我是 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");

   }    

}


UYOU
浏览 314回答 5
5回答

慕的地6264312

当你调用特定值时,你必须用ArgumentMatchers.eq().&nbsp;但是,您也可以使用anyString(),any(Class class)和其他。它们都是不言自明的。模拟教程。@Beforepublic void init (){&nbsp; &nbsp; MockitoAnnotations.initMocks(this);&nbsp; &nbsp; HttpEntity <?> request = new HttpEntity<>(reqPayload, headers);&nbsp; &nbsp; Mockito.when(restTemplate.getForEntity(ArgumentMatchers.eq("theUrl"),ArgumentMatchers.any(Map.class)))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .thenReturn(new ResponseEntity <Map>(someMap, HttpStatus.OK));}关于你的结构。这样你就可以RestTemplate通过构造函数注入。public class ServiceTester {&nbsp; &nbsp; @Mock&nbsp; &nbsp; private RestTemplate restTemplate;&nbsp; &nbsp; private Service service;&nbsp; &nbsp; @Before&nbsp; &nbsp; public void init (){&nbsp; &nbsp; &nbsp; &nbsp; MockitoAnnotations.initMocks(this);&nbsp; &nbsp; &nbsp; &nbsp; service = new Service(restTemplate);&nbsp; &nbsp; &nbsp; &nbsp; HttpEntity <?> request = new HttpEntity<>(reqPayload, headers);&nbsp; &nbsp; &nbsp; &nbsp; Mockito.when(restTemplate.getForEntity(ArgumentMatchers.eq("theUrl"),ArgumentMatchers.any(Map.class)))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .thenReturn(new ResponseEntity <Map>(someMap, HttpStatus.OK));&nbsp; &nbsp; }}class Service {&nbsp; &nbsp; private RestTemplate template;&nbsp; &nbsp; @Autowired&nbsp; &nbsp; public Service(RestTemplate template) {&nbsp; &nbsp; &nbsp; &nbsp; this.template = template;&nbsp; &nbsp; }&nbsp; &nbsp; public Map doSomething () {&nbsp; &nbsp; &nbsp; &nbsp; // do something with template&nbsp; &nbsp; }}

当年话下

我嘲笑这样的休息模板@RunWith(SpringRunner.class)public class Clazz {&nbsp; &nbsp; @Mock&nbsp; &nbsp; private RestTemplate restTemplate;}所以尝试使用 SpringRunner 而不是 MockitoRunner 也许它会起作用

哆啦的时光机

您确定要特别模拟 restTemplate 吗?不模拟 restTemplate 而是模拟答案怎么样?它还可以帮助您测试 restTemplate 行为。如果 restTemplate 得到 404 或 500 怎么办?这就是为什么我建议你使用MockRestServiceServer它有助于检查所有真实场景。

12345678_0001

你必须注入RestTemplate你的服务SomeService。目前,您正在服务中创建一个新实例。这意味着,您没有获得 的模拟实例RestTemplate,但获得了真实类的全新实例RestTemplate。你必须做这样的事情:class SomeService{&nbsp; &nbsp;@Inject&nbsp; &nbsp;private RestTemplate restTemplate;&nbsp; &nbsp;&nbsp; &nbsp;//some private, static,&nbsp; final data members&nbsp; &nbsp;public Map getService(String sNo, String uId, String en)&nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; ResponseEntity <Map> response = restTEmplate.getForEntity("https://someurl.com/someService",&nbsp;&nbsp; &nbsp; &nbsp; Map.class);&nbsp; &nbsp; &nbsp; ...&nbsp; &nbsp;}}

呼唤远方

如果您有权更改 SomeService 类,我建议您执行以下操作。class SomeService{&nbsp; &nbsp;//some private, static,&nbsp; final data members&nbsp; &nbsp;public Map getService(String sNo, String uId, String en)&nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; ResponseEntity <Map> response = getForEntity("https://someurl.com/someService", Map.class);&nbsp; &nbsp; &nbsp; Map body = response.getBody();&nbsp; &nbsp; &nbsp; //do something&nbsp; &nbsp; &nbsp; HttpEntity<?> request = new HttpEntity <>(payLoad, headers);&nbsp; &nbsp; &nbsp; //payload is Hash Map and headers is a LinkedMultiValueMap&nbsp; &nbsp; &nbsp; ResponseEntity <Map> response = postForEntity(url, request, headers);&nbsp; &nbsp; &nbsp; return response.getBody();&nbsp;&nbsp; &nbsp;}&nbsp; &nbsp;}正如您可能已经猜到的getForEntity那样,postForEntity方法已经被提取出来,RestTemplate 在其中被实例化——秘密地完成它的工作。既然你想从一开始就模拟 RestTemplate,我们摆脱它是一件好事——现在我们可以在没有任何对象模拟的情况下监视我们的服务。&nbsp; &nbsp; @RunWith(MockitoJunitRunner.class)&nbsp; &nbsp; class TestSomeService&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp;@InjectMocks&nbsp; &nbsp; &nbsp; &nbsp;@Spy&nbsp; &nbsp; &nbsp; &nbsp;SomeService ser;&nbsp; &nbsp; &nbsp; &nbsp;/*Some data members*/&nbsp; &nbsp; &nbsp; &nbsp;@Before&nbsp; &nbsp; &nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; HttpEntity <?> request = new HttpEntity<>(reqPayload, headers);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doReturn(new ResponseEntity <Map>(someMap, HttpStatus.OK))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .when(ser).getForEntity("theUrl", Map.class));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; doReturn(new ResponseEntity <Map>(expectedMap, HttpStatus.OK))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .when(ser).postForEntity("anotherUrl", request, Map.class));&nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; &nbsp; &nbsp; &nbsp;@Test&nbsp; &nbsp; &nbsp; &nbsp;public void testGetService()&nbsp; &nbsp; &nbsp; &nbsp;{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Map <String, Object> result = ser.getService("123", "abc", "QA");&nbsp; &nbsp; &nbsp; &nbsp;}&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; }
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java