我使用以下签名嘲笑了一些接缝组件:
@Name("myService")
@Install(debug = true, precedence = Install.MOCK)
public class MyServiceMock implements MyService
我通过更改components.xml
中的这一行来启用我的模拟<core:init transaction-management-enabled="false" />
到此:
<core:init transaction-management-enabled="false" debug="true" />
当我想模拟所有类时,这很好。我刚用我的ant脚本用调试版替换了我的普通components.xml。
有没有办法有条件地嘲笑一个或多个组件?一个理想的解决方案允许我指定在外部文件中模拟哪些组件,例如components.properties或其他属性文件。
以下是我根据germanescobar's回答确定的内容。
我更改了我的模拟组件签名以匹配:
@Name("myService")
@Install(false)
public class MyServiceMock implements MyService
然后我为要模拟的components.xml添加了一行代码,如下所示:
<component name="myService" installed="false" precedence="40"
class="com.foo.bar.baz.service.MyServiceMock" />
要启用模拟,我设置installed=true
。
答案 0 :(得分:1)
您可以依靠 org.jboss.seam.postInitialization 事件
当Seam初始化并启动所有组件时调用
or org.jboss.seam.postAuthenticate。&lt; username&gt;
在用户通过身份验证后调用,例如devMode
因此,创建您的ConformedEventComponent并定义其@Observer事件
@Name("conditionallyEventComponent")
@Scope(ScopeType.APPLICATION)
public class ConditionallyEvent {
@Observer("org.jboss.seam.postInitialization", create=true)
/*
* or @Observer("org.jboss.seam.postAuthenticate.devMode", create=true)
*/
public void postInitialization() {
/**
* An ideal solution would allow me to specify which components to mock out in an external file
*/
/**
* Here i am overriding ApplicationScoped components
*
* Maybe you want something like
* applicationContext.properties
* sessionContext.properties
*/
Context context = Contexts.getApplicationContext();
ResourceBundle resourceBundle = ResourceBundle.getBundle("applicationContext");
Enumeration<String> keyEnumeration = resourceBundle.getKeys();
while(keyEnumeration.hasMoreElements()) {
String key = keyEnumeration.nextElement();
/**
* Keep in mind newInstance method needs no-arg constructor
*/
context.set(key, Class.forName(resourceBundle.getString(key)).newInstance());
}
}
}
通过提供create属性,您还可以指定在事件被引发时是否存在创建观察者组件
您还可以按如下方式提供系统属性
-Dprofile=development
查看Application Server文档如何设置系统属性。在postInitialization(或postAuthenticate)事件
中@Observer("org.jboss.seam.postInitialization", create=true)
public void postInitialization() {
Properties properties = System.getProperties();
String profile = properties.getProperty("profile");
if(profile != null && profile.equals("development")) {
// do as shown above
}
}
答案 1 :(得分:1)
当我只想覆盖某些组件时,我通常会使用components.xml文件。因此,例如,如果我有一个MyService接口,其默认实现如下:
@Name("myService")
public class DefaultMyService implements MyService
我想只覆盖那个特定的类,我将以下内容添加到components.xml:
<component name="myService" class="org.gescobar.MockMyService" precedence="30" />
请看一下优先顺序。默认情况下,每个组件的优先级都为20,因此30将覆盖该组件。您可以将components.xml视为外部文件(或Spring用户的application-context.xml),您可以在其中覆盖所需的任何组件。