3

Say that Java application makes requests to http://www.google.com/... and there's no way to configure the inherited library (making such requests internally), so I can not stub or replace this URL.

Please, share some best practices to create a mock like

whenCalling("http://www.google.com/some/path").withMethod("GET").thenExpectResponse("HELLO")

so a request made by any HTTP client to this URL would be redirected to the mock and replaced with this response "HELLO" in the context of current JVM process.

I tried to find a solution using WireMock, Mockito or Hoverfly, but it seems that they do something different from that. Probably I just failed to use them properly.

Could you show a simple set up from the main method like:

  1. create mock
  2. start mock simulation
  3. make a request to the URL by an arbitrary HTTP client (not entangled with the mocking library)
  4. receive mocked response
  5. stop mock simulation
  6. make the same request as on step 3
  7. receive real response from URL
1
  • If you have no control over the code you might need to rewrite the call on your operating system level
    – Smutje
    Commented Mar 17, 2020 at 10:48

1 Answer 1

3

Here's how to achieve what you want with the API Simulator.

The example demonstrates two different ways to configure Embedded API Simulator as HTTP proxy for the Spring's RestTemplate client. Check with the documentation of the (quote from the question) "inherited library" - often times Java-based clients rely on system properties described here or may offer some way to configure HTTP proxy with code.

package others;

import static com.apisimulator.embedded.SuchThat.*;
import static com.apisimulator.embedded.http.HttpApiSimulation.*;

import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Proxy.Type;
import java.net.URI;

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import com.apisimulator.embedded.http.JUnitHttpApiSimulation;

public class EmbeddedSimulatorAsProxyTest
{

   // Configure an API simulation. This starts an instance of
   // Embedded API Simulator on localhost, default port 6090.
   // The instance is automatically stopped when the test ends.
   @ClassRule
   public static final JUnitHttpApiSimulation apiSimulation = JUnitHttpApiSimulation
         .as(httpApiSimulation("my-sim"));

   @BeforeClass
   public static void beforeClass()
   {
      // Configure simlets for the API simulation
      // @formatter:off
      apiSimulation.add(simlet("http-proxy")
         .when(httpRequest("CONNECT"))
         .then(httpResponse(200))
      );

      apiSimulation.add(simlet("test-google")
         .when(httpRequest()
               .whereMethod("GET")
               .whereUriPath(isEqualTo("/some/path"))
               .whereHeader("Host", contains("google.com"))
          )
         .then(httpResponse()
               .withStatus(200)
               .withHeader("Content-Type", "application/text")
               .withBody("HELLO")
          )
      );
      // @formatter:on
   }

   @Test
   public void test_using_system_properties() throws Exception
   {
      try
      {
         // Set these system properties just for this test
         System.setProperty("http.proxyHost", "localhost");
         System.setProperty("http.proxyPort", "6090");

         RestTemplate restTemplate = new RestTemplate();

         URI uri = new URI("http://www.google.com/some/path");
         ResponseEntity<String> response = restTemplate.getForEntity(uri, String.class);

         Assert.assertEquals(200, response.getStatusCode().value());
         Assert.assertEquals("HELLO", response.getBody());
      }
      finally
      {
         System.clearProperty("http.proxyHost");
         System.clearProperty("http.proxyPort");
      }
   }

   @Test
   public void test_using_java_net_proxy() throws Exception
   {
      SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();

      // A way to configure API Simulator as HTTP proxy if the HTTP client supports it
      Proxy proxy = new Proxy(Type.HTTP, new InetSocketAddress("localhost", 6090));
      requestFactory.setProxy(proxy);

      RestTemplate restTemplate = new RestTemplate();
      restTemplate.setRequestFactory(requestFactory);

      URI uri = new URI("http://www.google.com/some/path");
      ResponseEntity<String> response = restTemplate.getForEntity(uri, String.class);

      Assert.assertEquals(200, response.getStatusCode().value());
      Assert.assertEquals("HELLO", response.getBody());
   }

   @Test
   public void test_direct_call() throws Exception
   {
      RestTemplate restTemplate = new RestTemplate();

      URI uri = new URI("http://www.google.com");
      ResponseEntity<String> response = restTemplate.getForEntity(uri, String.class);

      Assert.assertEquals(200, response.getStatusCode().value());
      Assert.assertTrue(response.getBody().startsWith("<!doctype html>"));
   }

}

When using maven, add the following to project's pom.xml to include the Embedded API Simulator as a dependency:

    <dependency>
      <groupId>com.apisimulator</groupId>
      <artifactId>apisimulator-http-embedded</artifactId>
      <version>1.6</version>
    </dependency>

... and this to point to the repository:

  <repositories>
    <repository>
        <id>apisimulator-github-repo</id>
        <url>https://github.com/apimastery/APISimulator/raw/maven-repository</url>
     </repository>
  </repositories>
2
  • Great! That's probably even better than I supposed to have. Could you add to the answer the maven dependency, which is required for using API Simulator in a project? After that the answer will be complete and I'm going to accept it.
    – diziaq
    Commented Mar 19, 2020 at 5:12
  • Hi @diziaq -- edited the answer to add info on how to add the Embedded API Simulator as a dependency to maven-managed project. You should check out the real workhorse - the Standalone API Simulator :-) Cheers
    – apisim
    Commented Mar 20, 2020 at 2:26

Not the answer you're looking for? Browse other questions tagged or ask your own question.