猿问

如何在 restTemplate 上进行 junit 测试?

我在用 Mockito 模拟 restTemplate 时遇到问题


代码要测试:


public class Feature{

 public static String getfeature(String url){

     RestTemplate restTemplate = new RestTemplate();

     String xml = "\"feature\": 1";

     String json = restTemplate.postForObject(url, xml, String.class);

     return json;

}

}

联合代码:


@Mock

RestTemplate restTemplate=mock(RestTemplate.class);

@Test

public void testGetfeature(){

string testResponse= "\"feature\": 1";

Mockito.when((String)restTemplate.postForObject(

                Mockito.any(String.class),

                Mockito.any(Map.class),

                Mockito.any(Class.class)

                )).thenReturn(testResponse);

Feature feature = new Feature();

feature.getfeature("http://mockValue");

}

我在 feature.getfeature(" http://mockValue ")设置断点。它仍然尝试连接到远程服务器。我不希望 postForObject 连接到http://mockValue。我应该如何模拟 restTemplate 使 postForObject 不连接到http://mockValue



慕斯王
浏览 178回答 4
4回答

萧十郎

您正在方法中创建一个新RestTemplate对象getfeature()。所以,嘲笑RestTemplate没有效果。要么将RestTemplate其作为方法中的参数getfeature(),要么将其作为Feature类中的构造函数参数。然后从测试类中,您可以模拟 RestTemplate 并像下面这样传递它:Feature feature= new Feature(mockRestTemplate);feature.getfeature(url);或者Feature feature = new Feature();feature.getfeature(mockRestTemplate, url);您必须根据决定对要素类进行必要的更改。这是运行代码示例:主要类:public class Feature {    public static String getFeature(String url, RestTemplate restTemplate) {        return restTemplate.postForObject(url, "", String.class);    }}测试类:请注意模拟的方式RestTemplate,然后模拟响应。public class FeatureTest {    @Test    public void testFeature() {        RestTemplate restTemplate = Mockito.mock(RestTemplate.class);        Mockito.when(restTemplate.postForObject(Mockito.any(String.class),                Mockito.any(Object.class), Mockito.any(Class.class))).thenReturn("abc");        System.out.println(Feature.getFeature("http://abc", restTemplate));    }}运行代码示例也可以在github上找到Feature.java和FeatureTest.java

慕尼黑的夜晚无繁华

如何在 restTemplate 上进行 junit 测试?我们测试它返回的内容。目前你的实现本身什么都不做,它只是委托给 aRestTemplate并返回它的结果。答案fiveelements描述了实现(以广泛接受的值作为参数):@Test public void testFeature() {    RestTemplate restTemplate = Mockito.mock(RestTemplate.class);    Mockito.when(restTemplate.postForObject(Mockito.any(String.class),            Mockito.any(Object.class), Mockito.any(Class.class))).thenReturn("abc");    System.out.println(Feature.getFeature("http://abc", restTemplate));}这并没有断言实际行为:URL 可能是错误的,发布的正文或响应可能是错误的等等......而这个测试永远不会检测到这一点。最后,这个实现中可能有非常重要的事情是错误的,我们无法检测到。这种考验的价值,实在是太弱了。由于此方法本身不执行逻辑,因此它更适合于可以在实际行为中断言和捕获更多事物/问题的集成测试:@Test public void testFeature() {    String actualFeature = Feature.getFeature("http://...");    String expectedFeature = ...;    Assertions.assertEquals(expectedFeature, actualFeature);}

MYYA

我认为您需要更改代码以使您的单元测试至少使用 Mockito 工作,或者您必须使用其他一些库(如 powermock)来模拟本地对象实例化。1)创建一个构造函数,它接受 RestTemplate 作为参数来注入你的模拟。或者2) 创建一些 setter 方法来注入该 RestTemplate。另一种方法是创建另一个可以传递 RestTemplate 的方法。public String getStringAsJson(RestTemplate restTemplate, String url, String xml) {     return  restTemplate.postForObject(url, xml, String.class);}然后在你的测试中:RestTemplate mockRestTemplate = mock(RestTemplate.class);when(restTemplate.postForObject(mockurl, mockUrl, mockXml)).thenReturn("Json");feature.getStringAsJson(mockRestTemplate,mockUrl,mockXml);

桃花长相依

如果您使用PowerMockito,那么您可以执行以下操作:Feature 类无需更改代码,如果 prj 中有 PowerMockito lib,则可以直接使用它RestTemplate mockedRestTemplate = PowerMockito.mock(RestTemplate.class);PowerMockito.whenNew(RestTemplate.class).withAnyArguments().thenReturn(mockedRestTemplate);
随时随地看视频慕课网APP

相关分类

Java
我要回答