首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用RequestFixture在Ratpack中模拟会话?

如何使用RequestFixture在Ratpack中模拟会话?
EN

Stack Overflow用户
提问于 2018-06-12 10:21:49
回答 1查看 343关注 0票数 1

我想要做的是测试一个身份验证处理程序,但是我的问题归结为注册表中没有Session实例。

一个示例测试:

代码语言:javascript
复制
package whatever

import groovy.transform.CompileStatic
import ratpack.groovy.handling.GroovyChainAction
import ratpack.groovy.test.handling.GroovyRequestFixture
import ratpack.http.Status
import ratpack.session.Session
import spock.lang.Specification

class SessionChainTest extends Specification {
    GroovyChainAction sessionChain = new GroovyChainAction() {
        @Override
        @CompileStatic
        void execute() throws Exception {
            get('foo') {
                Session s = get Session
                // Stuff using session here
            }
        }
    }

    def "should get session"() {
        given:
        def result = GroovyRequestFixture.handle(sessionChain) {
            uri 'foo'
            method 'GET'
        }

        expect:
        result.status == Status.OK

        // If the server threw, rethrow that
        Throwable t = result.exception(Throwable)
        if (t) throw t // <<< Throws NotInRegistryException because no Session in registry
    }

}

(额外的重新抛出允许我们看到在棘轮包测试中抛出的异常,因为默认情况下它会被捕获并存储在结果中。)

我知道原则上我可以创建一个会话实例并使用一个registry { add <Session instance> }块将它添加到注册表中,但我已经深入研究了Ratpack代码,创建会话对象需要获取许多不同的其他组件并将它们传递给SessionModule#sessionAdaptor (或DefaultSession构造函数)。我找不到这样做的任何例子,看来这个调用是由Guice依赖注入魔术处理的,我无法取消。

在应用程序中,通常的方法是使用bind { module SessionModule }块,但这在RequestFixture#execute的上下文中是不可访问的。

由于会话对于任何web应用程序来说都是谋生手段,我的预感是这可能是一个很容易解决的问题,我只是还没有找到正确的方法来做呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-12 11:04:50

您可以通过Registry方法调用访问GroovyRequestFixture.handle(handler, closure),例如注册模拟的Session对象:

代码语言:javascript
复制
GroovyRequestFixture.handle(sessionChain) {
    uri 'foo'
    method 'GET'
    registry { r ->
        r.add(Session, session)
    }
}

请看下面的示例:

代码语言:javascript
复制
import groovy.transform.CompileStatic
import ratpack.exec.Promise
import ratpack.groovy.handling.GroovyChainAction
import ratpack.groovy.test.handling.GroovyRequestFixture
import ratpack.http.Status
import ratpack.jackson.internal.DefaultJsonRender
import ratpack.session.Session
import spock.lang.Specification

import static ratpack.jackson.Jackson.json

class SessionChainTest extends Specification {

    Session session = Mock(Session) {
        get('test') >> Promise.value(Optional.of('Lorem ipsum'))
    }

    GroovyChainAction sessionChain = new GroovyChainAction() {
        @Override
        @CompileStatic
        void execute() throws Exception {
            get('foo') {
                Session s = get Session

                s.get('test').map { Optional<String> o ->
                    o.orElse(null)
                }.flatMap { value ->
                    Promise.value(value)
                }.then {
                    render(json([message: it]))
                }
            }
        }
    }

    def "should get session"() {
        given:
        def result = GroovyRequestFixture.handle(sessionChain) {
            uri 'foo'
            method 'GET'
            registry { r ->
                r.add(Session, session)
            }
        }

        expect:
        result.status == Status.OK

        and:
        result.rendered(DefaultJsonRender).object == [message: 'Lorem ipsum']

    }
}

在这个测试中,我模拟Session对象,让键test存储Lorem ipsum文本。当运行此测试时,两个断言都会通过。

替代方法:注册Guice.registry()

如果不想使用模拟的Session对象,可以尝试用Guice注册表对象替换默认的Ratpack的Registry。首先,初始化一个创建Guice注册表并通过绑定添加SessionModule的函数:

代码语言:javascript
复制
static Function<Registry, Registry> guiceRegistry = Guice.registry { bindings ->
    bindings.module(new SessionModule())
}

接下来,在execute()方法的GroovyChainAction中,您可以通过调用以下命令来替换默认注册表:

代码语言:javascript
复制
register(guiceRegistry.apply(registry))

不再有模拟,但在这种情况下,您不能在请求范围之外访问Session对象,因此在测试的准备阶段您将无法向会话添加任何内容。下面可以找到完整的示例:

代码语言:javascript
复制
import groovy.transform.CompileStatic
import ratpack.exec.Promise
import ratpack.func.Function
import ratpack.groovy.handling.GroovyChainAction
import ratpack.groovy.test.handling.GroovyRequestFixture
import ratpack.guice.Guice
import ratpack.http.Status
import ratpack.jackson.internal.DefaultJsonRender
import ratpack.registry.Registry
import ratpack.session.Session
import ratpack.session.SessionModule
import spock.lang.Specification

import static ratpack.jackson.Jackson.json

class SessionChainTest extends Specification {

    static Function<Registry, Registry> guiceRegistry = Guice.registry { bindings ->
        bindings.module(new SessionModule())
    }

    GroovyChainAction sessionChain = new GroovyChainAction() {
        @Override
        @CompileStatic
        void execute() throws Exception {
            register(guiceRegistry.apply(registry))

            get('foo') {
                Session s = get Session

                s.get('test').map { Optional<String> o ->
                    o.orElse(null)
                }.flatMap { value ->
                    Promise.value(value)
                }.then {
                    render(json([message: it]))
                }
            }
        }
    }

    def "should get session"() {
        given:
        def result = GroovyRequestFixture.handle(sessionChain) {
            uri 'foo'
            method 'GET'
        }

        expect:
        result.status == Status.OK

        and:
        result.rendered(DefaultJsonRender).object == [message: null]

    }
}

希望能帮上忙。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50814817

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档