2017-02-23 97 views
4
public class ServiceTest { 
    @Mock 
    RestTemplate restTemplate = new RestTemplate(); 
    @InjectMocks 
    Service service = new Service(); 
    ResponseEntity responseEntity = mock(ResponseEntity.class); 

    @Test 
    public void test() throws Exception { 
     Mockito.when(restTemplate.getForEntity(
       Mockito.anyString(), 
       Matchers.any(Class.class) 
       )) 
       .thenReturn(responseEntity); 
     boolean res = service.isEnabled("something"); 
     Assert.assertEquals(res, false); 
    } 

我試圖測試包括restclient在內的服務的簡單測試。它看起來我沒有成功地模擬RestTemplate。它看起來像代碼獲取真實的數據而不是模擬的數據。任何人都可以幫助我。如何在Java Spring中模擬RestTemplate?

服務本身看起來這樣:

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; 
    } 
} 

回答

4

問題是,在isEnabled中,您正在創建一個新的RestTemplate。這是錯誤的,原因有兩個,一是你不能嘲笑它,因爲你正在創建一個新的,第二是避免每個請求創建新的對象。 RestTemplate是線程安全的,因此可以成爲服務類成員,用於跨多個線程。

服務類更改爲這樣的事情:

public class Service{ 

    RestTemplate restTemplate = new RestTemplate(); 

    public boolean isEnabled(String xxx) { 
     ResponseEntity<String> response = restTemplate.getForEntity("someurl",String.class); 
     if(...)return true; 
     return false; 
    } 
} 

現在你RestTemplate成了一個類的成員,你現在可以正確地通過以下兩種方式之一嘲笑。一,使用@InjectMock注入它,或者使用你從測試中調用的setter方法。

由於您在代碼中使用了InjectMock,我們可以使用它。

@RunWith(MockitoJUnitRunner.class) 
public class ServiceTest { 
    @Mock 
    RestTemplate restTemplate; 
    @InjectMocks 
    @Spy 
    Service service; 
    ResponseEntity responseEntity = mock(ResponseEntity.class); 

    @Test 
    public void test() throws Exception { 
     Mockito.when(restTemplate.getForEntity(
       Mockito.anyString(), 
       Matchers.any(Class.class) 
       )) 
       .thenReturn(responseEntity); 
     boolean res = service.isEnabled("something"); 
     Assert.assertEquals(res, false); 
    } 

請注意,我做了一些更改。首先,我刪除了new RestTemplate()new Service()。你應該讓mockito爲你創建這些。通過註釋@Mock@Spy,你將確保Mockito將爲你創建它們,更重要的是,將注入到你的service對象中。

3

Spring MVC的測試框架提供了單元測試RESTful服務代碼的類MockRestServiceServer

這是關於它的使用tutorial

+0

我試過教程,但它不起作用。 http://stackoverflow.com/questions/37781982/mocking-a-rest-call-with-mockrestserviceserver – c2340878

+0

https://github.com/jeffsheets/MockRestServiceServerExample –

0

如果使用@Autowired,則可以使用MockRestServiceServer。 以下是樣本。

@Service 
public class Service{ 
    @Autowired 
    private RestTemplate restTemplate; 

    public boolean isEnabled(String xxx) { 
     ResponseEntity<String> response = restTemplate.getForEntity("someurl",String.class); 
     if(...)return true; 
     return false; 
    } 
} 

@服務需要使用@Autowired自動創建對象。

+0

我試過了,但它會返回restTemplate爲null的錯誤。它看起來我不能注入restTemplate bean。還有什麼我可以做的測試嗎?我只需要模擬RestTemplete的響應。 – c2340878

+0

對不起,我錯過了將重要性註釋放在課堂上。請再看看我的答案。 – hiroyukik