Play framework 2.2.1: Create Http.Context for tests

為{幸葍}努か 提交于 2019-12-03 19:09:28

问题


I've been trying to create an Http.Context for tests using its constructor unsuccessfully. Does anybody see what I'm doing wrong?

I've looked at the following but it only applies to Play 2.0:

Play framework 2.0: Store values in Http.Context

It looks like the class changed for 2.2.1 and it has more parameters for the constructor as shown here:

https://github.com/playframework/playframework/blob/2.1.x/framework/src/play/src/main/java/play/mvc/Http.java

This my code:

import java.util.Map;
import java.util.Collections;
import org.junit.*;
import static org.mockito.Mockito.*;
import play.mvc.*;
import play.test.*;
import play.mvc.Http;
import play.mvc.Http.Context;
import play.api.mvc.RequestHeader;
import static play.test.Helpers.*;
import static org.fest.assertions.Assertions.*;


public class TemplateTests {

    public static FakeApplication app;
    private final Http.Request request = mock(Http.Request.class);

    @BeforeClass
    public static void startApp() {
        app = Helpers.fakeApplication();
        Helpers.start(app);
    }

    @Before
    public void setUp() throws Exception {
        Map<String, String> flashData = Collections.emptyMap();
        Map<String, Object> argData = Collections.emptyMap();
        Long id = 2L;
        play.api.mvc.RequestHeader header = mock(play.api.mvc.RequestHeader.class);
        Http.Context context = mock(Http.Context(id, header, request , flashData, flashData, argData));
        Http.Context.current.set(context);
    }


    @Test
    public void renderTemplate() {
        Content html = views.html.index.render();
        assertThat(contentType(html)).isEqualTo("text/html");
        assertThat(contentAsString(html)).contains("myindex");
    }

    @AfterClass
    public static void stopApp() {
        Helpers.stop(app);
    }
}

This is the error that I'm seeing when running a test:

play test
[info] Loading project definition from /home/user/solr-segmentexplorer/explorer/project
[info] Set current project to explorer (in build file:/home/user/solr-segmentexplorer/explorer/)
[info] Compiling 1 Java source to /home/user/solr-segmentexplorer/explorer/target/scala-2.10/test-classes...
[error] /home/user/solr-segmentexplorer/explorer/test/TemplateTests.java:33: cannot find symbol
[error] symbol  : method Context(java.lang.Long,play.api.mvc.RequestHeader,play.mvc.Http.Request,java.util.Map<java.lang.String,java.lang.String>,java.util.Map<java.lang.String,java.lang.String>,java.util.Map<java.lang.String,java.lang.Object>)
[error] location: class play.mvc.Http
[error]         Http.Context context = mock(Http.Context(id, header, request , flashData, flashData, argData));
[error]                                         ^
[error] 1 error
[error] (test:compile) javac returned nonzero exit code
[error] Total time: 3 s, completed Nov 25, 2013 11:56:36 PM

Any ideas?

If I don't create a context I get:

[error] Test TemplateTests.renderTemplate failed: java.lang.RuntimeException: There is no HTTP Context available from here.


回答1:


Looks like this seems to have fixed it for me:

@Before
public void setUp() throws Exception {
    Map<String, String> flashData = Collections.emptyMap();
    Map<String, Object> argData = Collections.emptyMap();
    Long id = 2L;
    play.api.mvc.RequestHeader header = mock(play.api.mvc.RequestHeader.class);
    Http.Context context = new Http.Context(id, header, request, flashData, flashData, argData);
    Http.Context.current.set(context);
}

The part that fixes it specifically is:

Http.Context.current.set(context);



回答2:


Just to provide an alternative using Mockito, only mocking just what you need (no manual instantiating of any class):

private Http.Context getMockContext() {
    Http.Request mockRequest = mock(Http.Request.class);
    when(mockRequest.remoteAddress()).thenReturn("127.0.0.1");
    when(mockRequest.getHeader("User-Agent")).thenReturn("mocked user-agent");

    // ... and so on. Mock precisely what you need, then add it to your mocked Context

    Http.Context mockContext = mock(Http.Context.class);
    when(mockContext.request()).thenReturn(mockRequest);
    when(mockContext.lang()).thenReturn(Lang.forCode("en"));

    return mockContext;
}

You could also verify if those fields have been used:

@Test
public void testMockContext() {
    final Http.Context mockContext = getMockContext();

    assertThat(mockContext.request()).isNotNull();
    verify(mockContext).request();

    final String remoteAddress = mockContext.request().remoteAddress();
    assertThat(remoteAddress).isNotNull();
    assertThat(remoteAddress).isEqualTo("127.0.0.1");
    verify(mockContext.request()).remoteAddress();
}

Don't forget to import static org.mockito.Mockito.*




回答3:


Just mocking context class solved the issue

@Before
public void setUp() throws Exception {
    Http.Context context = mock(Http.Context.class);
    Http.Context.current.set(context);
}



回答4:


As a combination of the other answers:

In build.sbt:

libraryDependencies += "org.mockito" % "mockito-core" % "1.10.19" % "test"

In your test class:

import play.mvc.Http;
import static org.mockito.Mockito.*;

@Before
public void setUp() throws Exception {
    Http.Context context = mock(Http.Context.class);
    Http.Flash flash = mock(Http.Flash.class);
    when(context.flash()).thenReturn(flash);
    Http.Context.current.set(context);
}

If you need more, just Mockito's functionalities. In case you are seeing any exceptions, just inspect the compiled code. IN my case, it was in target/scala-2.11/twirl/main/views/html/main.template.scala.



来源:https://stackoverflow.com/questions/20206270/play-framework-2-2-1-create-http-context-for-tests

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!