gpt4 book ai didi

java - 如何使用 RequestFixture 在 Ratpack 中模拟 session ?

转载 作者:行者123 更新时间:2023-11-30 06:08:19 25 4
gpt4 key购买 nike

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

示例测试:

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
}

}

(额外的重新抛出是为了让我们能够看到ratpack测试中抛出的异常,因为默认情况下它会被捕获并隐藏在结果中。)

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

在应用程序中执行此操作的常用方法是使用 bind { module SessionModule } block ,但这无法从 RequestFixture#execute 的上下文访问.

由于 session 对于任何网络应用程序来说都是面包和黄油,我的预感是这可能是一个很容易解决的问题,我只是还没有找到正确的方法来做到这一点?

最佳答案

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

GroovyRequestFixture.handle(sessionChain) {
uri 'foo'
method 'GET'
registry { r ->
r.add(Session, session)
}
}

看看下面的例子:

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']

}
}

在此测试中,我模拟关键 testSession 对象来存储 Lorem ipsum 文本。运行此测试时,两个断言均通过。

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

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

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

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

register(guiceRegistry.apply(registry))

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

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]

}
}

希望有帮助。

关于java - 如何使用 RequestFixture 在 Ratpack 中模拟 session ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50814817/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com