0
votes

I am using PlayFramework 2.5 and trying to unit test the headers that are set on my request, which is failing with the following message:

Test controllers.ApplicationTest.knownUnregister failed: java.lang.RuntimeException: There is no HTTP Context available from here.

My test class is:

package controllers;

import java.util.Optional;

import org.junit.Test;
import play.mvc.Http;
import play.mvc.Result;

import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;

public class MyAppTest {
  @Test public void knownUnregister() {
     MyApp app = new MyApp();
     Result res = app.registerEnv();
     Optional<String> url = res.header(Http.HeaderNames.LOCATION);
     assertTrue(url.isPresent());
  }
}

The source is:

package controllers;

import play.mvc.Controller;
import play.mvc.Result;
import play.mvc.Http;

public class MyApp extends Controller {
    public Result registerEnv() {
      response().setHeader(Http.HeaderNames.LOCATION, "/env/foo");
      return created("foo");
    }
}

I have seen Play framework 2.2.1: Create Http.Context for tests, which mocks the RequestHeader object. Doing that causes the test to fail with a null pointer exception, probably because the mocked object returns a null map for the header map.

Looking at the Mockito docs, before I figured out how to set up the mock correctly, I saw the parts of the documentation that said to not mock code that is not yours, and that if the code cares what the mock returns, then there is probably a problem with the test.

Since I care that the real result with have the correct headers set, it seem like creating a real, not mocked, Context is what I want to do here.

Is there a way to do that?

1
The only way without mocks is to have an integration test instead of a unit test. - marcospereira

1 Answers

0
votes

To write unit test you should derive your test class from WithApplication and call a controller method with Helpers class (of Play). It should be in your case something like this:

public class MyTest extends WithApplication {
    @Test  
     public void testSomething() {  
         Helpers.running(Helpers.fakeApplication(), () -> {
             Call action = controllers.routes.MyApp.registerEnv();  
             Result res = route(Helpers.fakeRequest(action)); 
             Optional<String> url = res.header(Http.HeaderNames.LOCATION);
             assertTrue(url.isPresent());
         });
     }  
}

You can find more examples here in my blog.