gpt4 book ai didi

java - 如何通过 Spock 测试进行 CDI/SE?

转载 作者:行者123 更新时间:2023-12-02 09:03:01 25 4
gpt4 key购买 nike

我一直在使用 CDIUnit 和其他各种形式的 CDI/SE 解决方案来实现测试 (junit),这些测试较少进行模拟并使用更多的应用程序堆栈(我想是集成测试)。

无论如何,我也非常喜欢 Spock 进行测试,并认为它应该能够快速地将 CDI/SE 空间和 spock 中的某些内容混搭起来,以便能够制定能够访问大多数 CDI 内容的规范。

许多 CDI 的单元运行程序(CDIUnit、weldjunit、deltaspike、为 SE 执行 cdi 或焊接的随机博客片段)——都是 JUnit 运行程序,并且似乎不太适合 Spock。经过多次修改,我已经提炼出一个非常简单的东西:weld/se + spock 和非常简单的@Inject。但这不起作用。

看起来焊接确实“启动”了,并且我的注入(inject)器的后构造函数被触发。然而,在 Spock 功能方法中,对可注入(inject)的引用为空。在进一步的测试中,我做了一个 @Inject setter 而不是实例变量,并且 setter 似乎确实使用非空引用触发,但是当我的功能方法触发时;引用再次为空。我还搞乱了 Weld 和容器 @Shared 并尝试在 setupSpec() 生命周期方法中进行初始化;相同的结果。

是否可以通过 Spock 测试执行简单的 CDI 操作?

这是 Spock 的一个示例 block ,它显示了我想要实现的目标:

package fhw

import spock.lang.Specification
import javax.inject.Inject
import org.jboss.weld.environment.se.Weld
import org.jboss.weld.environment.se.WeldContainer
import spock.lang.Shared

public class Chompers
extends Specification
{
def Weld weld
def WeldContainer container

def setup()
{
println this
weld = new Weld()
container = weld.initialize()
container.instance().select(this.class).get()
//container.instance().select(this.class)
}

@Inject
def SomethingToTest somethingToTest;

//@Inject
//def setSomethingToTest(SomethingToTest sst)
//{
// somethingToTest = sst
// println "setter fired and somethingToTest is null? " + (null == somethingToTest)
//}

def "my first Test"()
{
given:
println "given I used weld wrapper spec From spock (instance " + this + ")"


when:
println "when I do something, in this case, like just haveing @Inject annotation"

then:
somethingToTest
}
}

更新

我有一些有点“工作”的东西。不知道为什么或如何,甚至不确定它是否有任何好处(对于解决方案)。我想更多地了解正在发生的事情以及原因。示例:

package fhw

import org.junit.runner.RunWith
import spock.lang.*
import org.jboss.weld.environment.se.Weld
import org.jboss.weld.environment.se.WeldContainer
import javax.enterprise.inject.Instance

class WeldSpec
extends Specification
{

def Weld weld
def WeldContainer container
def me

def setup()
{
weld = new Weld()
container = weld.initialize()
me = container.instance().select(this.class).get()
}

def cleanup()
{
if(weld)
{
weld.shutdown()
}
}
}
<小时/>
package fhw

import spock.lang.*
import javax.inject.Inject
import fhw.spock.*

public class Bonnie
extends WeldSpec
{
@Inject
def SomethingToTest somethingToTest;

def "my silly first cdi-spock test"()
{
when:
def s = me.somethingToTest.upShift("fred")

then:
"FRED" == s
}
}
<小时/>
package fhw;

import javax.annotation.PostConstruct;
import javax.inject.Named;


@Named
public class SomethingToTest
{
public SomethingToTest() {}

@PostConstruct
private void init()
{
System.out.println("SomethingToTest: post construction");
}


public String upShift(String in)
{
String s = null;
if(null != in)
{
s = in.toUpperCase();
}
return(s);
}

}
<小时/>

更新2

所以我观察/猜测,真正发生的事情是 spock 创建了我的规范的一个实例(“this”),然后在使用焊接/se 的设置中,我使用 select().get() 调用创建了另一个实例('我')。简单的 printlns 显示 'me' != 'this' 并且注入(inject)实际上发生在通过 select().get() 创建的托管实例上。或者说我是这么认为的。

所以我认为我真正想要的是在“this”上进行注入(inject)。一些谷歌搜索,我偶然发现了这个:CDI inject into existing object这是类似的东西。我受到 DeltaSpike 的注入(inject)字段的“启发”并重构了 WeldSpec,如下所示:

package fhw

import spock.lang.*
import javax.enterprise.inject.spi.BeanManager
import javax.enterprise.inject.spi.InjectionTarget
import org.jboss.weld.environment.se.Weld
import org.jboss.weld.environment.se.WeldContainer
import javax.enterprise.context.spi.CreationalContext
import javax.enterprise.inject.spi.AnnotatedType

class WeldSpec
extends Specification
{
def Weld weld
def WeldContainer container

def setup()
{
weld = new Weld()
container = weld.initialize()
BeanManager beanManager = container.getBeanManager()
CreationalContext<? extends WeldSpec> creationalContext = beanManager.createCreationalContext(null)
AnnotatedType<? extends WeldSpec> annotatedType = beanManager.createAnnotatedType((Class<? extends WeldSpec>) this.getClass())
InjectionTarget<? extends WeldSpec> injectionTarget = beanManager.createInjectionTarget(annotatedType)
injectionTarget.inject(this, creationalContext);
}

def cleanup()
{
if(weld)
{
weld.shutdown()
}
}
}
<小时/>

这可行,而且我的规范更自然:

package fhw

import spock.lang.*
import javax.inject.Inject
import fhw.spock.*

public class Bonnie
extends WeldSpec
{
@Inject
def SomethingToTest somethingToTest;

def "my silly first cdi-spock test"()
{
when:
def s = somethingToTest.upShift("fred")

then:
"FRED" == s
}
}
<小时/>

现在要弄清楚这是否有什么好处......

最佳答案

按照更新 2;我有东西在工作。

关于java - 如何通过 Spock 测试进行 CDI/SE?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29749847/

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