Jak na mock HTTP serveru

 data-srcset
 data-srcset

Pro jednoho z naších zákazníků dodáváme C2DM – zasílání notifikací na mobilní telefon s operačním systémem Android. Tato služba je implementována jako HTTP request, ve kterém pošlete zprávu, registrační identifikátor instance zařízení s androidem a C2DM server se postará o doručení.

Narazil jsem ale na problém jak vytvořit unit test, který ověří správný formát odesílané notifikace. Problém je právě v tom, jak namockovat chování C2DM serveru bez toho, abych musel někde rozbíhat Jetty či nedejbože Tomcat. Testovaný kód vypadá nějak takto:

private static int sendMessage(String message, URL url) throws IOException {
  // create connection 
  HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  connection.setDoInput(true);
  connection.setDoOutput(true);
  connection.setRequestMethod("POST");

  // post data 
  DataOutputStream output = new DataOutputStream(connection.getOutputStream());
  output.writeBytes("message="message);
  output.flush();
  output.close();

  // establish connection 
  connection.connect(); 

  // return errocode 
  return connection.getResponseCode();
}

Umím vytvořit mock interfacu (viz. EasyMock , PowerMock ect.), dokonce i stub konkrétní třídy. Final třídu

URL zkrátka nepodědíte a testovanému kódu pak „nepředhodíte“. Narazil jsem na knihovnu simple, která velice jednoduše na několika řádcích na pár sekund rozběhne „webový server“. Vy pak můžete snadno nasimulovat chování protějšího serveru. Vytvoříte třídu implementující interface org.simpleframework.http.core.Container

public class MockC2dmServer implements Container {
  protected String capturedMessage;
  
  public void handle(Request request, Response response) {
    try {
      capturedMessage = request.getParameter("message");
    } catch (IOException e1) {
      capturedMessage = null;
    } 
    if(capturedMessage != null) {
      response.setCode(HttpURLConnection.HTTP_OK);
    } else {
      response.setCode(HttpURLConnection.HTTP_BADREQUEST);
    }
  }
}

Samotné vytvoření serveru a test pak může vypadat nějak takto:

@Test public void basicSenderTest() throws Exception {
  MockC2dmServer mockServer = new MockC2dmServer();
  // binds server to socket on adress
  Connection connectionServer = new SocketConnection(mockServer);
  SocketAddress address = new InetSocketAddress("localhost", 8080));
  connectionServer.connect(address);
  // test method
  String message = "message text";
  C2dmNotificationSender.sendNotification(message, new URL("http://localhost:8080");
  Assert.assertEquals(message, mockServer.capturedMessage);
}

Uznávám, že tento způsob testování má svá rizika, například vám nikdo nezaručí, že port 8080 bude volný, to však jde minimalizovat například metodou, která vám nějaký volný port najde, ale to už není tématem tohoto článku. Pokud někdo z vás přijde na jiné, lepší řešení rád si ho přečtu v diskuzi pod článkem.

Zpět

Posuňte s námi své služby dál.

Nasměrujeme vás správným směrem!

Kontakujte nás