简体   繁体   中英

How to mock new instance of RestTemplate?

Im writing a unit test for my legacy code which is something like:

public class SomeClass {
public SomeResponse logToServer() {
    SomeResponse response = null;
    try{ 
        RestTemplate restTemplate = new RestTemplate();
        SomeRequestBean request = new SomeRequestBean();
        response = restTemplate.postForEntity("http://someUrl", request, SomeResponse.class);
        System.out.println(response.toString());
    } catch(Exception e) {
        e.printStackTrace();
    } 
    return response;
}

}

I know I can move RestTemplate above and annotate it as @AutoWire and declare it as bean class or use power mockito to mock the new instance creation. But I don't wanna change this legacy code and I'm avoiding using power Mockito at all cost because just for one test I don't wanna add a whole new dependency to my pom.xml . So just wondering is there any way using which I can mock this restTemplate ?

To answer you question, no under the restrictions you've posted there is no way to mock RestTemplate and unit test it.

I do think that you can slightly change the legacy code because this change is not functional and in this case it might worth it. But I'll stick with you that you can't.

Regarding power mock and power mockito. Although I agree that these tools should be avoided but not for a reason that you've posted. Note, that this dependency is of test scope, it won't reach the production anyway even for legacy envrionments. So if the priority is to not change the legacy code, then introducing PowerMock is the "least evil".

If we're talking specifically about the rest template though, you can take advantage of some facts about spring rest template specifically that can be used for testing it anyway.

Option 1

The first technique (if the environment permits) is using @RestClientTest annotation. It will allow specifying the service under test and will provide a mock implemetation of something called MockRestServiceServer that will represent the server you're trying to connect to in the mocked environment. Then you'll be able to specify the expectations from this server and hopefully the code will run. Caution: this is not a unit test - this is an integration test that starts spring context, so it will much heavier/slower than regular unit test.

Here you can find a working example of this approach, check out this article it contains also other techniques.

Option 2

The idea behind the second technique is that RestTemplate is actually a wrapper above client libraries, it doesn't do any http intercommunication by itself.

It can be configured to work with HttpClient of apache, OkHttpClient, by default it works with URLConnection opening connection for each request. So You could create a test that would configure the rest client to run with some particular engine of your interest/choice and then check out how to test code that uses this engine directly. The solutions will be different depending on the actual engine used in the project.

So just wondering is there any way using which i can mock this restTemplate ?

Short Answer: No

Based on stated restrictions,

But I don't wanna change this legacy code and im avoiding using power Mockito at all cost because just for one test i dont wanna add a whole new dependency to my pom.xml

there is likely no other way to mock the restTemplate .

The subject code is tightly coupled to implementation details/concerns that make testing it in isolation difficult without the use of external dependencies/tools or refactoring the code to make it testable.

This is a case of technical debt calling in its loan.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM