使用 spring 测试 EJB 拦截器
Testing EJB interceptor using spring
我想测试(使用功能测试)被 EJB Iterceptor 拦截的 EJB 服务。此应用程序 运行 在 WildFly 服务器上。
测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {FooServiceTest.ClassContextTest.class})
public class FooServiceTest {
@Autowired public FooServiceImpl service;
@Test
public void createTest() throws Exception {
Foo foo = new Foo();
// ...
service.create(foo);
// ...
}
@Configuration
public static class ClassContextTest {
@Bean
public FooServiceImpl produceService() {
return new FooServiceImpl();
}
@Bean
public FooDao produceDao() {
//...
}
}
}
服务:
@Stateless
@Interceptors({ValidationInterceptor.class})
public class FooServiceImpl implements FooService {
private FooDao dao;
@Inject
public void setDao(FooDao dao) {
this.dao = dao;
}
public void create(@Valid Foo foo) {
// ...
dao.create(foo);
// ...
}
//...
}
拦截器:
public class ValidationInterceptor {
private Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
@AroundInvoke
public Object intercept(InvocationContext ctx) throws Exception {
Object[] paramValues = ctx.getParameters();
Parameter[] params = ctx.getMethod().getParameters();
for (int i = 0; i < params.length; i++) {
if (params[i].isAnnotationPresent(Valid.class)) {
Object value = paramValues[i];
valid(value);
}
}
return ctx.proceed();
}
private void valid(Object value) throws ConstraintViolationException {
Set<ConstraintViolation<Object>> violations = validator.validate(value);
if (!violations.isEmpty()) {
Set<ConstraintViolation<?>> cvs = new HashSet<>();
for (ConstraintViolation<?> cv : violations) {
cvs.add(cv);
}
throw new ConstraintViolationException(cvs);
}
}
}
我的测试设法测试了服务、DAO 和映射器,但根本没有调用拦截器。我猜这是因为我在 Spring 测试中使用了 JavaEE 拦截器,但我不知道如何让它工作。
我正在使用 Spring 4.3 和 JavaEE 7。
我使用 weld-junit4 来使用 weld 作为容器而不是 Spring。
public class FooServiceTest {
@Rule
public WeldInitiator weld = WeldInitiator.from(FooServiceImpl.class, this.getClass()).build();
public FooServiceImpl service;
private static DataSource ds;
@BeforeClass
public static void beforeClass() {
ds = h2DataSource();
}
@Test
public void createTest() throws Exception {
Foo foo = new Foo();
// ...
service.create(foo);
// ...
}
@Produces
public FooDao produceDao() {
FooDao dao = new FooDao() {};
dao.setDataSource(ds);
return dao;
}
public static DataSource h2DataSource() {
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).addScript("my/path/scripts.sql").build();
}
}
通过这种方式,我能够对 @Interceptors
和 @Inject
使用 JavaEE 注入,并使用 Spring 使用 H2 模拟数据库。
我想测试(使用功能测试)被 EJB Iterceptor 拦截的 EJB 服务。此应用程序 运行 在 WildFly 服务器上。
测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {FooServiceTest.ClassContextTest.class})
public class FooServiceTest {
@Autowired public FooServiceImpl service;
@Test
public void createTest() throws Exception {
Foo foo = new Foo();
// ...
service.create(foo);
// ...
}
@Configuration
public static class ClassContextTest {
@Bean
public FooServiceImpl produceService() {
return new FooServiceImpl();
}
@Bean
public FooDao produceDao() {
//...
}
}
}
服务:
@Stateless
@Interceptors({ValidationInterceptor.class})
public class FooServiceImpl implements FooService {
private FooDao dao;
@Inject
public void setDao(FooDao dao) {
this.dao = dao;
}
public void create(@Valid Foo foo) {
// ...
dao.create(foo);
// ...
}
//...
}
拦截器:
public class ValidationInterceptor {
private Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
@AroundInvoke
public Object intercept(InvocationContext ctx) throws Exception {
Object[] paramValues = ctx.getParameters();
Parameter[] params = ctx.getMethod().getParameters();
for (int i = 0; i < params.length; i++) {
if (params[i].isAnnotationPresent(Valid.class)) {
Object value = paramValues[i];
valid(value);
}
}
return ctx.proceed();
}
private void valid(Object value) throws ConstraintViolationException {
Set<ConstraintViolation<Object>> violations = validator.validate(value);
if (!violations.isEmpty()) {
Set<ConstraintViolation<?>> cvs = new HashSet<>();
for (ConstraintViolation<?> cv : violations) {
cvs.add(cv);
}
throw new ConstraintViolationException(cvs);
}
}
}
我的测试设法测试了服务、DAO 和映射器,但根本没有调用拦截器。我猜这是因为我在 Spring 测试中使用了 JavaEE 拦截器,但我不知道如何让它工作。 我正在使用 Spring 4.3 和 JavaEE 7。
我使用 weld-junit4 来使用 weld 作为容器而不是 Spring。
public class FooServiceTest {
@Rule
public WeldInitiator weld = WeldInitiator.from(FooServiceImpl.class, this.getClass()).build();
public FooServiceImpl service;
private static DataSource ds;
@BeforeClass
public static void beforeClass() {
ds = h2DataSource();
}
@Test
public void createTest() throws Exception {
Foo foo = new Foo();
// ...
service.create(foo);
// ...
}
@Produces
public FooDao produceDao() {
FooDao dao = new FooDao() {};
dao.setDataSource(ds);
return dao;
}
public static DataSource h2DataSource() {
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).addScript("my/path/scripts.sql").build();
}
}
通过这种方式,我能够对 @Interceptors
和 @Inject
使用 JavaEE 注入,并使用 Spring 使用 H2 模拟数据库。