我有一些EJB作为JAX-WS Web服务:
@WebService
@Stateless
@Remote(MobileFacade.class)
public class MobileFacadeBean implements MobileFacade {
...
@Resource
WebServiceContext wsc;
...
}
在此Web Service类中,通过@Resource注入WebServiceContext。我使用此WebServiceContext来获取实现中的主体。这很有效,但现在我想知道如何(单位)测试这个类!
到目前为止,我正在使用OpenEJB来测试我的EJB。由于Web Service类也是无状态会话Bean,我真的想在这里使用相同的方法。但是,它并不那么容易 - 当然,它抱怨在没有被称为Web服务时没有WebServiceContext。
所以第一个问题是:有没有办法在OpenEJB中模拟WebServiceContext?
如果不是,您会采用什么方法来测试这种Web服务类?
干杯, 弗兰克
答案 0 :(得分:5)
OpenEJB示例zip文件中有少量@WebService
单元测试示例。你想要的一切都应该可以正常工作。
webservice-security示例听起来与您想要的完全一样。在线版本使用@RolesAllowed
使容器进行安全检查而不是在代码中进行,但可以在代码中检查原则。以下是该示例的略微修改版本,对我没有任何问题。
@DeclareRoles(value = {"Administrator"})
@Stateless
@WebService(
portName = "CalculatorPort",
serviceName = "CalculatorWsService",
targetNamespace = "http://superbiz.org/wsdl",
endpointInterface = "org.superbiz.calculator.CalculatorWs")
public class CalculatorImpl implements CalculatorWs, CalculatorRemote {
@Resource
private WebServiceContext webServiceContext;
@RolesAllowed(value = {"Administrator"})
public int sum(int add1, int add2) {
// maybe log the principal or something -- prints "jane" in the test
System.out.print(webServiceContext.getUserPrincipal());
return add1 + add2;
}
@RolesAllowed(value = {"Administrator"})
public int multiply(int mul1, int mul2) {
return mul1 * mul2;
}
}
public class CalculatorTest extends TestCase {
private InitialContext initialContext;
protected void setUp() throws Exception {
Properties properties = new Properties();
properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.LocalInitialContextFactory");
properties.setProperty("openejb.embedded.remotable", "true");
initialContext = new InitialContext(properties);
}
/**
* Create a webservice client using wsdl url
*
* @throws Exception
*/
public void testCalculatorViaWsInterface() throws Exception {
URL url = new URL("http://127.0.0.1:4204/CalculatorImpl?wsdl");
QName calcServiceQName = new QName("http://superbiz.org/wsdl", "CalculatorWsService");
Service calcService = Service.create(url, calcServiceQName);
assertNotNull(calcService);
CalculatorWs calc = calcService.getPort(CalculatorWs.class);
((BindingProvider) calc).getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "jane");
((BindingProvider) calc).getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "waterfall");
assertEquals(10, calc.sum(4, 6));
assertEquals(12, calc.multiply(3, 4));
}
}
如果使用maven,请将您的正常openejb-core
依赖关系切换为openejb-cxf
,如此。这将把Apache CXF和OpenEJB / CXF集成代码添加到类路径中。
<dependency>
<groupId>org.apache.openejb</groupId>
<artifactId>openejb-cxf</artifactId>
<version>3.1.4</version>
<scope>test</scope>
</dependency>
如果不使用maven,最简单的方法是只添加OpenEJB zip文件的lib/
目录中的所有jar。
答案 1 :(得分:0)
大卫,在您使用CalculatorTest的答案中,您使用了CalculatorWs.class,它是否与在Web服务端实现中使用的界面相同。我们是否必须创建Web服务客户端?
也在大卫的例子中而不是
QName calcServiceQName = new QName("http://superbiz.org/wsdl", "CalculatorWsService");
使用
QName calcServiceQName = new QName("http://superbiz.org/wsdl", "CalculatorPort");