播放框架& CAS - 如何登录进行功能测试?

时间:2012-08-13 14:55:23

标签: java testing functional-testing cas playframework-1.x

我正在使用Play 1.2.4和CAS 3.1作为安全模块。在开发过程中一切正常,我必须登录才能使用我的控制器方法。

但是我无法让日志部分在我的功能测试中工作。我使用这个问题作为参考: Playframework Secure module: how do you "log in" to test a secured controller in a FunctionalTest?

我的测试看起来像这样:

@Test
public void testThatIndexPageWorks() {

    final Map<String, String> loginUserParams = new HashMap<String, String>();
    loginUserParams.put("login", "foobar");
    loginUserParams.put("password", "foobar");
    final Response loginResponse = POST("/@cas/authenticate", loginUserParams);

    final Request request = newRequest();
    request.cookies = loginResponse.cookies; // makes the request authenticated
    request.url = "/";
    request.method = "GET";
    final Response response = makeRequest(request);
    assertIsOk(response);
}

测试在“POST(”/ @ cas ......)“行失败,但有以下异常:

java.lang.RuntimeException: java.util.concurrent.ExecutionException: play.exceptions.ActionNotFoundException: Action null?ticket=ST-e71ba57f-3f1f-4b71-b16f-0141db78b42f not found
    at play.test.FunctionalTest.makeRequest(FunctionalTest.java:299)
    at play.test.FunctionalTest.makeRequest(FunctionalTest.java:305)
    at play.test.FunctionalTest.POST(FunctionalTest.java:152)
    at play.test.FunctionalTest.POST(FunctionalTest.java:200)
    at play.test.FunctionalTest.POST(FunctionalTest.java:167)
    at ApplicationTest.testThatIndexPageWorks(ApplicationTest.java:53)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at play.test.PlayJUnitRunner$StartPlay$2$1.evaluate(PlayJUnitRunner.java:105)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at play.test.PlayJUnitRunner.run(PlayJUnitRunner.java:55)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:24)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:136)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:117)
    at play.test.TestEngine.run(TestEngine.java:112)
    at controllers.TestRunner.run(TestRunner.java:66)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:548)
    at play.mvc.ActionInvoker.invoke(ActionInvoker.java:502)
    at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:478)
    at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:473)
    at play.mvc.ActionInvoker.invoke(ActionInvoker.java:161)
    at play.server.PlayHandler$NettyInvocation.execute(PlayHandler.java:257)
    at play.Invoker$Invocation.run(Invoker.java:278)
    at play.server.PlayHandler$NettyInvocation.run(PlayHandler.java:235)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:98)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:206)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)
Caused by: java.util.concurrent.ExecutionException: play.exceptions.ActionNotFoundException: Action null?ticket=ST-e71ba57f-3f1f-4b71-b16f-0141db78b42f not found
    at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:232)
    at java.util.concurrent.FutureTask.get(FutureTask.java:91)
    at play.test.FunctionalTest.makeRequest(FunctionalTest.java:286)
    ... 57 more
Caused by: play.exceptions.ActionNotFoundException: Action null?ticket=ST-e71ba57f-3f1f-4b71-b16f-0141db78b42f not found
    at play.mvc.ActionInvoker.getActionMethod(ActionInvoker.java:590)
    at play.mvc.Controller.redirect(Controller.java:555)
    at play.mvc.Controller.redirect(Controller.java:532)
    at play.mvc.Controller.redirect(Controller.java:501)
    at controllers.modules.cas.MockServer.loginAction(MockServer.java:51)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at play.mvc.ActionInvoker.invokeWithContinuation(ActionInvoker.java:548)
    at play.mvc.ActionInvoker.invoke(ActionInvoker.java:502)
    at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:478)
    at play.mvc.ActionInvoker.invokeControllerMethod(ActionInvoker.java:473)
    at play.mvc.ActionInvoker.invoke(ActionInvoker.java:161)
    at play.test.FunctionalTest$1.execute(FunctionalTest.java:269)
    at play.Invoker$Invocation.run(Invoker.java:278)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    ... 3 more
Caused by: java.lang.Exception: Controller controllers not found
    ... 22 more

看起来认证本身有效,因为我得到了某种票。

有没有人知道如何通过CAS从功能测试登录我的应用程序或者在运行测试时一起禁用CAS / @With(SecureCAS.class)?

1 个答案:

答案 0 :(得分:0)

设置CAS以使用MockServer作为播放测试配置文件,在application.conf中添加:

%test.cas.mockserver=true

然后

@Test
public void testThatIndexPageWorks() {
        // test with cas functionality
        final Map<String, String> loginUserParams = new HashMap<String, String>();
        loginUserParams.put("login", "foobar");
        loginUserParams.put("password", "foobar");
        loginUserParams.put("serviceUrl", "modules.cas.securecas/authenticate"); // must be set but is not used
        final Response authenticateResponse = POST("/@cas/authenticate", loginUserParams);
        // you get a redirect to the authenticate service: assertEquals(Integer.valueOf(302), authenticateResponse.status);

        // extract the ticket from the redirect url:
        String location = authenticateResponse.getHeader("Location");
        String ticket = location.substring(location.indexOf("ticket=")+7, location.length());
        Logger.debug("ticket: "+ticket);

        // odd workaround: we have to set the port and create the request by ourself, otherwise play is calling the url without port!
        final int port = Http.Request.current() == null ? 80 : Http.Request.current().get().port;
        final Request authenticateRequest = newRequest();
        authenticateRequest.port = port;
        final Response validateResponse = GET(authenticateRequest, "/modules.cas.securecas/authenticate?service=cas/serviceValidate&ticket="+ticket);
        // the response is again a redirect, normally to the initially called page:  assertEquals(Integer.valueOf(302), authenticateResponse.status);
        Logger.debug("Authentication successfull");

         // functional test of a html page:
         final Request request = newRequest();
         request.url = "/";
         request.cookies = validateResponse.cookies; // makes the request authenticated
         request.method = "GET";
         final Response response = makeRequest(request);
         assertIsOk(response);
}