在不使用模拟的情况下为PlayFramework测试创建上下文

时间:2016-06-17 18:55:44

标签: java playframework playframework-2.5

我正在使用PlayFramework 2.5并尝试对我的请求中设置的标头进行单元测试,但是失败时出现以下消息:

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

我的测试课程是:

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());
  }
}

来源是:

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");
    }
}

我见过Play framework 2.2.1: Create Http.Context for tests,它嘲笑RequestHeader对象。这样做会导致测试因空指针异常而失败,可能是因为模拟对象返回标题映射的空映射。

看看Mockito文档,在我弄清楚如何正确设置模拟之前,我看到文档的部分说不是模拟不属于你的代码,如果代码关心模拟返回的内容,那么测试可能存在问题。

因为我关心真正的结果是否设置了正确的标题,所以看起来像创建一个真实的,而不是模拟的,Context是我想要在这里做的。

有办法吗?

1 个答案:

答案 0 :(得分:0)

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.