Openejb与异常映射器的休息集成测试 [英] Openejb rest integration tests with exception mappers

查看:239
本文介绍了Openejb与异常映射器的休息集成测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为我的jax-rs服务编写一些集成测试,其中有一组异常映射器。因此,当执行给定的请求时,我希望基于异常映射器的某个响应代码。问题是,在这种环境中运行时,我无法获取异常映射器被调用。



我的服务应该在我的测试中抛出一个logicalexception:

  @Stateless 
@Path(/ baseCustomer)
public class BaseCustomerService {
@EJB //这个在单元测试中被嘲笑
private BaseCustomerManagerBean customerManager;

@POST
@Path(crud)
@Consumes({MediaType.APPLICATION_XML})
@Produces({MediaType.APPLICATION_XML,MediaType.TEXT_XML} )
public Hkunde createCustomer(Hkunde newCustomer)throws LogicalException {
//根据嘲笑抛出异常
return customerManager.createCustomer(newCustomer);
}

异常映射器:

  @Provider 
public class LogicalExceptionMapper实现ExceptionMapper< LogicalException> {

@Override
public Response toResponse(LogicalException exception){
return Response.status(Response.Status.FORBIDDEN).build();
}
}

我设置了我的测试:

  @Mock 
private BaseCustomerManagerBean baseCustomerManager;
private HttpClient httpClient;
私人BaseCustomerServiceClient客户端;

@Configuration
public属性config()throws异常{
属性属性= new Properties();
properties.setProperty(Context.INITIAL_CONTEXT_FACTORY,org.apache.openejb.client.RemoteInitialContextFactory);
properties.setProperty(OpenEjbContainer.OPENEJB_EMBEDDED_REMOTABLE,Boolean.TRUE.toString());

properties.setProperty(DeploymentFilterable.CLASSPATH_INCLUDE,LogicalExceptionMapper.class.getName());
properties.setProperty(openejb.jaxrs.providers.auto,true);
properties.setProperty(openejb.servicemanager.enabled,true);
返回属性;
}

@MockInjector
public Class<?> mockitoInjector(){
return MockitoInjector.class;


@Module
public EjbModule createModule()throws Exception {
final StatelessBean bean =(StatelessBean)new StatelessBean(BaseCustomerService.class).localBean();
bean.setRestService(true);

final EjbJar ejbJar = new EjbJar();
ejbJar.addEnterpriseBean(bean);

final OpenejbJar openejbJar = new OpenejbJar();
openejbJar.addEjbDeployment(new EjbDeployment(ejbJar.getEnterpriseBeans()[0]));

EjbModule module = new EjbModule(ejbJar);
module.setOpenejbJar(openejbJar);

返回模块;
}
@Module
public Class [] exceptionMappers(){
return new Class [] {LogicalExceptionMapper.class};
}

@Before
public void setup(){
ServiceHost serviceHost = new ServiceHost(http:// localhost:4204 / BaseCustomerServiceTest);
httpClient = new HttpClient(serviceHost);
client = new BaseCustomerServiceClient(httpClient);
}

@Test
public void createCustomer_givenLogicalException_expectsLogicalException()throws LogicalException {
Hkunde expected = new Hkunde(true);

当(baseCustomerManager.createCustomer(expected)))thenThrow(new LogicalException(mock));

try {
client.createCustomer(expected);
fail(Expected LogicalException);
} catch(LogicalException ex){
}

verify(baseCustomerManager).createCustomer(expected);
}

所以当我执行测试,我的客户端将从响应中读取响应代码,并根据此代码抛出异常。



问题是异常映射器从不被调用,我总是收到500内部服务器错误,而不是禁止的响应。我想我需要在设置ejbjar或类似的东西时添加一些更多的信息。



谢谢!

解决方案

这个例子 http://svn.apache.org/repos/asf/openejb/trunk/openejb/examples/rest-applicationcomposer/src/test/ java / org / superbiz / organized / rest / GreetingServiceTest.java (通过 http://rmannibucau.wordpress.com/2012/09/13/use-mockito-with-openejb/ ;-))显示你想要的。



openejbJar.addEjbDeployment(... 之后)添加以下内容,它应该可以工作。

  final属性= openejbJar.getEjbDeployment()。iterator()。next()。getProperties(); 
properties.setProperty(cxf.jaxrs.p roviders,LogicalExceptionMapper.class.getName());

这里是一个最小的工作示例(使用openejb-cxf-rs 4.5.0和openejb-core 4.5 .0):

  import java.util.Properties; 
import javax.ejb.Singleton;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.openejb.OpenEjbContainer;
import org.apache.openejb.config.EjbModule;
import org.apache.openejb.jee.EjbJar;
import org.apache.openejb.jee.StatelessBean;
import org.apache.openejb.jee.oejb3.EjbDeployment;
import org.apache.openejb.jee.oejb3.OpenejbJar;
import org.apache.openejb.junit.ApplicationComposer;
import org.apache.openejb.junit.Configuration;
import org.apache.openejb.junit.Module;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(ApplicationComposer.class)
public class RestWithExceptionMapper {

@Configuration
public属性配置(){
返回新属性(){
{
setProperty(OpenEjbContainer.OPENEJB_EMBEDDED_REMOTABLE,Boolean.TRUE.toString());
}
};
}

@Module
public EjbModule app(){
final StatelessBean bean =(StatelessBean)new StatelessBean(MyResource.class).localBean();
bean.setRestService(true);
final EjbJar ejbJar = new EjbJar();
ejbJar.addEnterpriseBean(bean);
final OpenejbJar openejbJar = new OpenejbJar();
openejbJar.addEjbDeployment(new EjbDeployment(ejbJar.getEnterpriseBeans()[0]));
final属性= openejbJar.getEjbDeployment()。iterator()。next()。getProperties();
properties.setProperty(cxf.jaxrs.providers,MyExceptionMapper.class.getName());
final EjbModule module = new EjbModule(ejbJar);
module.setOpenejbJar(openejbJar);
返回模块;
}

public static class FooException extends RuntimeException {
}

public static class MyExceptionMapper实现ExceptionMapper&FooException> {

@Override
public Response toResponse(final FooException t){
return Response.ok(Objection!)。build();
}
}

@Path(value =/ test)
public static class MyResource {

@GET
@Path(value =/ throw)
public String throwException(){
throw new FooException();
}
}

@Test
public void checkServiceWasDeployed(){
assertEquals(Objection!,WebClient.create(http://本地主机:4204 / RestWithExceptionMapper )路径(/测试/扔)得到(String.class));
}
}


I'm writing some integration tests towards my jax-rs service where I have a set of exception mappers. So, when performing a given request I expect a certain response code based on the exception mapper. The problem is that I cannot get the exception mappers to be invoked when running in this environment.

My service which should throw a logicalexception in my test:

@Stateless
@Path("/baseCustomer")
public class BaseCustomerService {
    @EJB //this one gets mocked in the unittest
    private BaseCustomerManagerBean customerManager;

    @POST
    @Path("crud")
    @Consumes({MediaType.APPLICATION_XML})
    @Produces({MediaType.APPLICATION_XML, MediaType.TEXT_XML})
    public Hkunde createCustomer(Hkunde newCustomer) throws LogicalException {
        //throws exception according to mocking
        return customerManager.createCustomer(newCustomer); 
    }

And the exception mapper:

@Provider
public class LogicalExceptionMapper implements ExceptionMapper<LogicalException> {

    @Override
    public Response toResponse(LogicalException exception) {
        return Response.status(Response.Status.FORBIDDEN).build();
    }
} 

I set up my tests like this:

@Mock
private BaseCustomerManagerBean baseCustomerManager;
private HttpClient httpClient;
private BaseCustomerServiceClient client;

@Configuration
public Properties config() throws Exception {
    Properties properties = new Properties();
    properties.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.RemoteInitialContextFactory");
    properties.setProperty(OpenEjbContainer.OPENEJB_EMBEDDED_REMOTABLE, Boolean.TRUE.toString());

    properties.setProperty(DeploymentFilterable.CLASSPATH_INCLUDE, LogicalExceptionMapper.class.getName());
    properties.setProperty("openejb.jaxrs.providers.auto", "true");
    properties.setProperty("openejb.servicemanager.enabled", "true");
    return properties;
}

@MockInjector
public Class<?> mockitoInjector() {
    return MockitoInjector.class;
}

@Module
public EjbModule createModule() throws Exception {
    final StatelessBean bean = (StatelessBean) new StatelessBean(BaseCustomerService.class).localBean();
    bean.setRestService(true);

    final EjbJar ejbJar = new EjbJar();
    ejbJar.addEnterpriseBean(bean);

    final OpenejbJar openejbJar = new OpenejbJar();
    openejbJar.addEjbDeployment(new EjbDeployment(ejbJar.getEnterpriseBeans()[0]));

    EjbModule module = new EjbModule(ejbJar);
    module.setOpenejbJar(openejbJar);

    return module;
}
@Module
public Class[] exceptionMappers() {
    return new Class[]{LogicalExceptionMapper.class};
}

@Before
public void setup() {
    ServiceHost serviceHost = new ServiceHost("http://localhost:4204/BaseCustomerServiceTest");
    httpClient = new HttpClient(serviceHost);
    client = new BaseCustomerServiceClient(httpClient);
}

@Test
public void createCustomer_givenLogicalException_expectsLogicalException() throws LogicalException {
    Hkunde expected = new Hkunde(true);

    when(baseCustomerManager.createCustomer(expected)).thenThrow(new LogicalException("mock"));

    try {
        client.createCustomer(expected);
        fail("Expected LogicalException");
    } catch (LogicalException ex) {
    }

    verify(baseCustomerManager).createCustomer(expected);
}

So when I execute the test, my client will read the response code from the response and throw an exception based on this code.

The problem is that the exception mapper is never invoked, and I always receive a 500 internal server error, instead of the "forbidden" response. I'm guessing I need to add some more info when setting up the ejbjar or something like that.

Thanks!

解决方案

This example http://svn.apache.org/repos/asf/openejb/trunk/openejb/examples/rest-applicationcomposer/src/test/java/org/superbiz/composed/rest/GreetingServiceTest.java (via http://rmannibucau.wordpress.com/2012/09/13/use-mockito-with-openejb/ ;-)) shows exactly what you want.

Add the following after openejbJar.addEjbDeployment(... and it should work.

final Properties properties = openejbJar.getEjbDeployment().iterator().next().getProperties();
properties.setProperty("cxf.jaxrs.providers", LogicalExceptionMapper.class.getName());

Here is a minimal working example (using openejb-cxf-rs 4.5.0 and openejb-core 4.5.0):

import java.util.Properties;
import javax.ejb.Singleton;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.ExceptionMapper;
import org.apache.cxf.jaxrs.client.WebClient;
import org.apache.openejb.OpenEjbContainer;
import org.apache.openejb.config.EjbModule;
import org.apache.openejb.jee.EjbJar;
import org.apache.openejb.jee.StatelessBean;
import org.apache.openejb.jee.oejb3.EjbDeployment;
import org.apache.openejb.jee.oejb3.OpenejbJar;
import org.apache.openejb.junit.ApplicationComposer;
import org.apache.openejb.junit.Configuration;
import org.apache.openejb.junit.Module;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(ApplicationComposer.class)
public class RestWithExceptionMapper {

    @Configuration
    public Properties configuration() {
        return new Properties() {
            {
                setProperty(OpenEjbContainer.OPENEJB_EMBEDDED_REMOTABLE, Boolean.TRUE.toString());
            }
        };
    }

    @Module
    public EjbModule app() {
        final StatelessBean bean = (StatelessBean) new StatelessBean(MyResource.class).localBean();
        bean.setRestService(true);
        final EjbJar ejbJar = new EjbJar();
        ejbJar.addEnterpriseBean(bean);
        final OpenejbJar openejbJar = new OpenejbJar();
        openejbJar.addEjbDeployment(new EjbDeployment(ejbJar.getEnterpriseBeans()[0]));
        final Properties properties = openejbJar.getEjbDeployment().iterator().next().getProperties();
        properties.setProperty("cxf.jaxrs.providers", MyExceptionMapper.class.getName());
        final EjbModule module = new EjbModule(ejbJar);
        module.setOpenejbJar(openejbJar);
        return module;
    }

    public static class FooException extends RuntimeException {
    }

    public static class MyExceptionMapper implements ExceptionMapper<FooException> {

        @Override
        public Response toResponse(final FooException t) {
            return Response.ok("Objection!").build();
        }
    }

    @Path(value = "/test")
    public static class MyResource {

        @GET
        @Path(value = "/throw")
        public String throwException() {
            throw new FooException();
        }
    }

    @Test
    public void checkServiceWasDeployed() {
        assertEquals("Objection!", WebClient.create("http://localhost:4204/RestWithExceptionMapper").path("/test/throw").get(String.class));
    }
}

这篇关于Openejb与异常映射器的休息集成测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆