如何通过嘲笑来模仿resttemplate

时间:2019-05-30 02:36:51

标签: java mocking resttemplate

我想模拟一个resttemplate请求,但似乎不起作用。 这是我要测试的课程:

public class SomeUtil {
    public static OrderInstanceResponse doGet(String url, otherargs...) {
       //some code...
       ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestHeader, String.class, requestMap);
       //another code...
    }
}

这是测试班:

@RunWith(MockitoJUnitRunner.class)
public class SomeUtilTest {
    @Mock
    private RestTemplate restTemplate;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void doGet() {
        OrderInstanceResponse exceptResponse = OrderInstanceResponse.builder().code("123").build();
        OrderInstanceRequest request = OrderInstanceRequest.builder().userId("123").build();

        Map<String, Object> testMap = new HashMap<>(1);
        testMap.put("userId", "123");

        Mockito.when(restTemplate.exchange(Mockito.anyString(), Mockito.any(), Mockito.any(), Mockito.eq(String.class), Mockito.eq(testMap)))
                .thenReturn(new ResponseEntity<>("\"code\":\"123\"", HttpStatus.OK));

        OrderInstanceResponse actualResponse = RestTemplateUtil.doGet("123", request, "123");
        Assert.assertEquals(actualResponse.getCode(), exceptResponse.getCode());
    }
}

运行此测试时出现一些错误: java.lang.IllegalArgumentException: URI is not absolute

似乎模拟不起作用,真正的请求是“ 123”。

如何解决此错误?谢谢

2 个答案:

答案 0 :(得分:0)

您需要将RestTemplate实例作为依赖项传递给RestTemplateUtil,而不是在doGet方法中实例化。然后,在单元测试中,将模拟RestTemplate实例传递给RestTemplateUtil。

public class SomeUtil {
    public SomeUtil(RestTemplate restTemplate) { this.restTemplate = restTemplate }
    public OrderInstanceResponse doGet(String url, otherargs...) {
        ResponseEntity<String> responseEntity = this.restTemplate.exchange(...
    }
}

或者如果您想将其保留为静态方法,则将RestTemplate作为参数传递。

答案 1 :(得分:0)

我找到了解决方案。 当我们需要模拟由new创建的对象时,例如RestTemplate rest = new RestTemplate(),应这样写:

PowerMockito.whenNew(ObjectToBeMocked.class).withAnyArguments().thenReturn(mockedObject);

然后添加注释@PrepareForTest({TheClassToBeTested.class})。请注意,参数是包含new获取的对象的类。 因此,完整的代码如下:

@RunWith(MockitoJUnitRunner.class)
@PrepareForTest({SomeUtil.class})
public class SomeUtilTest {

    @Mock
    private RestTemplate restTemplate;

    @Test
    public void doGet() {
        //......
        PowerMockito.whenNew(RestTemplate.class).withAnyArguments().thenReturn(restTemplate);
        //......
    }
}

感谢所有帮助过我的朋友。