简体   繁体   中英

How to mock HttpUrlConnection in JAX-RS

I am trying to do a mock test for my class, but it does not work.

Original class:

public class Service {
  .................
  @POST
  ...
  public Message Info(@NotNull @Valid final UUID Id) throws IOException {
    ............
    String httpLink = Config.getLink();
    ...
    if ( ...) { 
      HttpURLConnection urlConnection = null;
      URL url = new URL(OriginalLink);
      urlConnection = (HttpURLConnection) url.openConnection();
      urlConnection.setDoOutput(true);
      urlConnection.setRequestMethod("GET");
      urlConnection.setUseCaches(false);
      urlConnection.setConnectTimeout(50000);
      urlConnection.setReadTimeout(50000);
      urlConnection.setRequestProperty("Content-Type", "application/json");
      urlConnection.connect();
      .................
      String jsonobject = "..."; //data to be posted into api
      .......
    } else {
      return new Message("No data to posted from file");
    }
    return new Message("successfully posted data from file");
  }
}
  

Test class:

@Before
public void before() {
  MockitoAnnotations.initMocks(this);
  URL u = PowerMockito.mock(URL.class);
  String url = "url";
  PowerMockito.whenNew(URL.class).withArguments(url).thenReturn(u);
  HttpURLConnection huc = PowerMockito.mock(HttpURLConnection.class);
  PowerMockito.when(u.openConnection()).thenReturn(huc);
  PowerMockito.when(huc.getResponseCode()).thenReturn(200);
  .....
  PowerMockito.when(Config.getLink())
    .thenReturn("url");
}
 @Test
 public void testInfo() throws IOException {
    ............
    Message org = new Message("successfully posted data from file");
    Message msg = Service.Info(uuid);
    assertEquals(msg,org);
 }

I tried to mock using Mockito and PowerMockRunner but it did not work. With PowerMockito, i get "java.lang.NullPointerException"

With your implementation, you cannot mock the HttpURLConnection , because this is created in a non-mockable instance of URL that is created inside your method with new URL(OriginalLink);

You would have to create the URL with some kind of factory that you inject into the service, then you can mock that service to provide a mocked URL instance, and that mocked URL instance would have to provide a mocked HttpURLConnection instance.

Or you extract the part that creates the connection to the URL into an extra method that gets the URL and returns the connected HttpURLConnection. Then you can test that method extra and mock or spy it "away" for the test of the other method.

Something like

class ConnectionService {
  HttpURLConnection openConnection(URL connectTo) {
    HttpURLConnection urlConnection = (HttpURLConnection) connectTo.openConnection();
    urlConnection.setDoOutput(true);
    urlConnection.setRequestMethod("GET");
    urlConnection.setUseCaches(false);
    urlConnection.setConnectTimeout(50000);
    urlConnection.setReadTimeout(50000);
    urlConnection.setRequestProperty("Content-Type", "application/json");
    urlConnection.connect();
    return urlConnection;
  }
}

And in your code then:

// get connectionService injected
URL url = new URL(OriginalLink);
HttpURLConnection urlConnection = connectionService.openConnection(url);

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