You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by rm...@apache.org on 2012/09/11 14:59:11 UTC
svn commit: r1383394 - in /openejb/trunk/openejb:
arquillian/arquillian-openejb-embedded-4/
arquillian/arquillian-openejb-embedded-4/src/main/java/org/apache/openejb/arquillian/openejb/
arquillian/arquillian-openejb-embedded-4/src/main/java/org/apache/...
Author: rmannibucau
Date: Tue Sep 11 12:59:10 2012
New Revision: 1383394
URL: http://svn.apache.org/viewvc?rev=1383394&view=rev
Log:
OPENEJB-1899 openejb applicationcomposer + mockito (and arquillian + mockito sample test)
Added:
openejb/trunk/openejb/arquillian/arquillian-openejb-embedded-4/src/main/java/org/apache/openejb/arquillian/openejb/mockito/
openejb/trunk/openejb/arquillian/arquillian-openejb-embedded-4/src/main/java/org/apache/openejb/arquillian/openejb/mockito/MockitoEnricher.java
openejb/trunk/openejb/arquillian/arquillian-openejb-embedded-4/src/test/java/org/apache/openejb/arquillian/openejb/ArquillianAndMockitoTest.java
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/junit/TestInstance.java
openejb/trunk/openejb/utils/openejb-mockito/
openejb/trunk/openejb/utils/openejb-mockito/pom.xml
openejb/trunk/openejb/utils/openejb-mockito/src/
openejb/trunk/openejb/utils/openejb-mockito/src/main/
openejb/trunk/openejb/utils/openejb-mockito/src/main/java/
openejb/trunk/openejb/utils/openejb-mockito/src/main/java/org/
openejb/trunk/openejb/utils/openejb-mockito/src/main/java/org/apache/
openejb/trunk/openejb/utils/openejb-mockito/src/main/java/org/apache/openejb/
openejb/trunk/openejb/utils/openejb-mockito/src/main/java/org/apache/openejb/mockito/
openejb/trunk/openejb/utils/openejb-mockito/src/main/java/org/apache/openejb/mockito/MockRegistry.java
openejb/trunk/openejb/utils/openejb-mockito/src/main/java/org/apache/openejb/mockito/MockitoExtension.java
openejb/trunk/openejb/utils/openejb-mockito/src/main/java/org/apache/openejb/mockito/MockitoInjector.java
openejb/trunk/openejb/utils/openejb-mockito/src/main/resources/
openejb/trunk/openejb/utils/openejb-mockito/src/main/resources/META-INF/
openejb/trunk/openejb/utils/openejb-mockito/src/main/resources/META-INF/services/
openejb/trunk/openejb/utils/openejb-mockito/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
openejb/trunk/openejb/utils/openejb-mockito/src/test/
openejb/trunk/openejb/utils/openejb-mockito/src/test/java/
openejb/trunk/openejb/utils/openejb-mockito/src/test/java/org/
openejb/trunk/openejb/utils/openejb-mockito/src/test/java/org/apache/
openejb/trunk/openejb/utils/openejb-mockito/src/test/java/org/apache/openejb/
openejb/trunk/openejb/utils/openejb-mockito/src/test/java/org/apache/openejb/mockito/
openejb/trunk/openejb/utils/openejb-mockito/src/test/java/org/apache/openejb/mockito/Facade.java
openejb/trunk/openejb/utils/openejb-mockito/src/test/java/org/apache/openejb/mockito/Hello.java
openejb/trunk/openejb/utils/openejb-mockito/src/test/java/org/apache/openejb/mockito/MockitoAndAppComposerTest.java
openejb/trunk/openejb/utils/openejb-mockito/src/test/resources/
openejb/trunk/openejb/utils/openejb-mockito/src/test/resources/META-INF/
openejb/trunk/openejb/utils/openejb-mockito/src/test/resources/META-INF/beans.xml
Modified:
openejb/trunk/openejb/arquillian/arquillian-openejb-embedded-4/pom.xml
openejb/trunk/openejb/arquillian/arquillian-openejb-embedded-4/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBInjectionEnricher.java
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/junit/ApplicationComposer.java
openejb/trunk/openejb/utils/pom.xml
Modified: openejb/trunk/openejb/arquillian/arquillian-openejb-embedded-4/pom.xml
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/arquillian/arquillian-openejb-embedded-4/pom.xml?rev=1383394&r1=1383393&r2=1383394&view=diff
==============================================================================
--- openejb/trunk/openejb/arquillian/arquillian-openejb-embedded-4/pom.xml (original)
+++ openejb/trunk/openejb/arquillian/arquillian-openejb-embedded-4/pom.xml Tue Sep 11 12:59:10 2012
@@ -99,6 +99,13 @@
<artifactId>arquillian-openejb-transaction-provider</artifactId>
<version>${tomee.version}</version>
</dependency>
+
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>1.9.0</version>
+ <scope>test</scope>
+ </dependency>
</dependencies>
<build>
Modified: openejb/trunk/openejb/arquillian/arquillian-openejb-embedded-4/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBInjectionEnricher.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/arquillian/arquillian-openejb-embedded-4/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBInjectionEnricher.java?rev=1383394&r1=1383393&r2=1383394&view=diff
==============================================================================
--- openejb/trunk/openejb/arquillian/arquillian-openejb-embedded-4/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBInjectionEnricher.java (original)
+++ openejb/trunk/openejb/arquillian/arquillian-openejb-embedded-4/src/main/java/org/apache/openejb/arquillian/openejb/OpenEJBInjectionEnricher.java Tue Sep 11 12:59:10 2012
@@ -24,6 +24,7 @@ import org.apache.openejb.AppContext;
import org.apache.openejb.BeanContext;
import org.apache.openejb.InjectionProcessor;
import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.arquillian.openejb.mockito.MockitoEnricher;
import org.apache.openejb.core.Operation;
import org.apache.openejb.core.ThreadContext;
import org.apache.openejb.spi.ContainerSystem;
@@ -46,6 +47,9 @@ public class OpenEJBInjectionEnricher im
return;
}
+ // don't rely on arquillian since this enrichment should absolutely be done before the following ones
+ new MockitoEnricher().enrich(testInstance);
+
final BeanManager bm = ctx.getWebBeansContext().getBeanManagerImpl();
try {
final Set<Bean<?>> beans = bm.getBeans(testInstance.getClass());
Added: openejb/trunk/openejb/arquillian/arquillian-openejb-embedded-4/src/main/java/org/apache/openejb/arquillian/openejb/mockito/MockitoEnricher.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/arquillian/arquillian-openejb-embedded-4/src/main/java/org/apache/openejb/arquillian/openejb/mockito/MockitoEnricher.java?rev=1383394&view=auto
==============================================================================
--- openejb/trunk/openejb/arquillian/arquillian-openejb-embedded-4/src/main/java/org/apache/openejb/arquillian/openejb/mockito/MockitoEnricher.java (added)
+++ openejb/trunk/openejb/arquillian/arquillian-openejb-embedded-4/src/main/java/org/apache/openejb/arquillian/openejb/mockito/MockitoEnricher.java Tue Sep 11 12:59:10 2012
@@ -0,0 +1,44 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.arquillian.openejb.mockito;
+
+import org.jboss.arquillian.test.spi.TestEnricher;
+
+import java.lang.reflect.Method;
+
+/**
+ * do it by reflection to avoid to need mockito
+ */
+public class MockitoEnricher implements TestEnricher {
+ private static final String MOCKITO_CLASS = "org.mockito.MockitoAnnotations";
+
+ @Override
+ public void enrich(final Object testCase) {
+ try {
+ final Class<?> clazz = testCase.getClass().getClassLoader().loadClass(MOCKITO_CLASS);
+ final Method injectMethod = clazz.getMethod("initMocks", Object.class);
+ injectMethod.invoke(null, testCase);
+ } catch (Exception e) {
+ // no-op: can't use mockito, not a big deal for common cases
+ }
+ }
+
+ @Override
+ public Object[] resolve(final Method method) {
+ return new Object[method.getParameterTypes().length];
+ }
+}
Added: openejb/trunk/openejb/arquillian/arquillian-openejb-embedded-4/src/test/java/org/apache/openejb/arquillian/openejb/ArquillianAndMockitoTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/arquillian/arquillian-openejb-embedded-4/src/test/java/org/apache/openejb/arquillian/openejb/ArquillianAndMockitoTest.java?rev=1383394&view=auto
==============================================================================
--- openejb/trunk/openejb/arquillian/arquillian-openejb-embedded-4/src/test/java/org/apache/openejb/arquillian/openejb/ArquillianAndMockitoTest.java (added)
+++ openejb/trunk/openejb/arquillian/arquillian-openejb-embedded-4/src/test/java/org/apache/openejb/arquillian/openejb/ArquillianAndMockitoTest.java Tue Sep 11 12:59:10 2012
@@ -0,0 +1,50 @@
+package org.apache.openejb.arquillian.openejb;
+
+import org.jboss.arquillian.container.test.api.Deployment;
+import org.jboss.arquillian.junit.Arquillian;
+import org.jboss.shrinkwrap.api.ArchivePaths;
+import org.jboss.shrinkwrap.api.ShrinkWrap;
+import org.jboss.shrinkwrap.api.asset.EmptyAsset;
+import org.jboss.shrinkwrap.api.spec.JavaArchive;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+
+import javax.enterprise.inject.Produces;
+import javax.inject.Inject;
+
+import static org.junit.Assert.assertNotNull;
+
+@RunWith(Arquillian.class)
+public class ArquillianAndMockitoTest {
+ @Inject
+ private AFooBean bean;
+
+ @Mock @Produces
+ private static AnInterface mock;
+
+ @Deployment
+ public static JavaArchive archive() {
+ return ShrinkWrap.create(JavaArchive.class, ArquillianAndMockitoTest.class.getSimpleName().concat(".jar"))
+ .addClasses(AnInterface.class, AFooBean.class)
+ .addAsManifestResource(EmptyAsset.INSTANCE, ArchivePaths.create("beans.xml"));
+ }
+
+ @Test
+ public void mockWorks() {
+ assertNotNull(bean);
+ assertNotNull(mock);
+ assertNotNull(bean.get());
+ }
+
+ public static interface AnInterface {}
+
+ public static class AFooBean {
+ @Inject
+ private AnInterface mock;
+
+ public AnInterface get() {
+ return mock;
+ }
+ }
+}
Modified: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/junit/ApplicationComposer.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/junit/ApplicationComposer.java?rev=1383394&r1=1383393&r2=1383394&view=diff
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/junit/ApplicationComposer.java (original)
+++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/junit/ApplicationComposer.java Tue Sep 11 12:59:10 2012
@@ -199,13 +199,45 @@ public class ApplicationComposer extends
appModule.getEjbModules().add(new EjbModule(ejbJar, openejbJar));
}
+ // For the moment we just take the first @Configuration method
+ // maybe later we can add something fancy to allow multiple configurations using a qualifier
+ // as a sort of altDD/altConfig concept. Say for example the altDD prefix might be "foo",
+ // we can then imagine something like this:
+ // @Foo @Configuration public Properties alternateConfig(){...}
+ // @Foo @Module public Properties alternateModule(){...}
+ // anyway, one thing at a time ....
+
+ final Properties configuration = new Properties();
+ configuration.put(DEPLOYMENTS_CLASSPATH_PROPERTY, "false");
+
+ final List<FrameworkMethod> methods = testClass.getAnnotatedMethods(Configuration.class);
+ for (FrameworkMethod method : methods) {
+ final Object o = method.invokeExplosively(testInstance);
+ if (o instanceof Properties) {
+ Properties properties = (Properties) o;
+ configuration.putAll(properties);
+ }
+ break;
+ }
+
+ if (SystemInstance.isInitialized()) SystemInstance.reset();
+
+ SystemInstance.init(configuration);
+
+ // save the test under test to be able to retrieve it from extensions
+ // /!\ has to be done before all other init
+ SystemInstance.get().setComponent(TestInstance.class, new TestInstance(testClass.getJavaClass(), testInstance));
+
// call the mock injector before module method to be able to use mocked classes
- FallbackPropertyInjector mockInjector = null;
+ // it will often use the TestInstance so
final List<FrameworkMethod> mockInjectors = testClass.getAnnotatedMethods(MockInjector.class);
for (FrameworkMethod method : mockInjectors) { // max == 1 so no need to break
- final Object o = method.invokeExplosively(testInstance);
+ Object o = method.invokeExplosively(testInstance);
+ if (o instanceof Class<?>) {
+ o = ((Class<?>) o).newInstance();
+ }
if (o instanceof FallbackPropertyInjector) {
- mockInjector = (FallbackPropertyInjector) o;
+ SystemInstance.get().setComponent(FallbackPropertyInjector.class, (FallbackPropertyInjector) o);
}
}
@@ -320,35 +352,6 @@ public class ApplicationComposer extends
appModule = newModule;
}
- // For the moment we just take the first @Configuration method
- // maybe later we can add something fancy to allow multiple configurations using a qualifier
- // as a sort of altDD/altConfig concept. Say for example the altDD prefix might be "foo",
- // we can then imagine something like this:
- // @Foo @Configuration public Properties alternateConfig(){...}
- // @Foo @Module public Properties alternateModule(){...}
- // anyway, one thing at a time ....
-
- final Properties configuration = new Properties();
- configuration.put(DEPLOYMENTS_CLASSPATH_PROPERTY, "false");
-
- final List<FrameworkMethod> methods = testClass.getAnnotatedMethods(Configuration.class);
- for (FrameworkMethod method : methods) {
- final Object o = method.invokeExplosively(testInstance);
- if (o instanceof Properties) {
- Properties properties = (Properties) o;
- configuration.putAll(properties);
- }
- break;
- }
-
- if (SystemInstance.isInitialized()) SystemInstance.reset();
-
- SystemInstance.init(configuration);
-
- if (mockInjector instanceof FallbackPropertyInjector) {
- SystemInstance.get().setComponent(FallbackPropertyInjector.class, mockInjector);
- }
-
try {
ConfigurationFactory config = new ConfigurationFactory();
config.init(SystemInstance.get().getProperties());
Added: openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/junit/TestInstance.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/junit/TestInstance.java?rev=1383394&view=auto
==============================================================================
--- openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/junit/TestInstance.java (added)
+++ openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/junit/TestInstance.java Tue Sep 11 12:59:10 2012
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.junit;
+
+public class TestInstance {
+ protected Class<?> testClass;
+ protected Object instance;
+
+ public TestInstance(final Class<?> testClass, final Object instance) {
+ this.testClass = testClass;
+ this.instance = instance;
+ }
+
+ public Class<?> getTestClass() {
+ return testClass;
+ }
+
+ public Object getInstance() {
+ return instance;
+ }
+}
Added: openejb/trunk/openejb/utils/openejb-mockito/pom.xml
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/utils/openejb-mockito/pom.xml?rev=1383394&view=auto
==============================================================================
--- openejb/trunk/openejb/utils/openejb-mockito/pom.xml (added)
+++ openejb/trunk/openejb/utils/openejb-mockito/pom.xml Tue Sep 11 12:59:10 2012
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>utils</artifactId>
+ <groupId>org.apache.openejb</groupId>
+ <version>4.1.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>openejb-mockito</artifactId>
+ <name>OpenEJB :: Utils :: Mockito</name>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.openejb</groupId>
+ <artifactId>openejb-core</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.mockito</groupId>
+ <artifactId>mockito-core</artifactId>
+ <version>1.9.0</version>
+ </dependency>
+ </dependencies>
+</project>
Added: openejb/trunk/openejb/utils/openejb-mockito/src/main/java/org/apache/openejb/mockito/MockRegistry.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/utils/openejb-mockito/src/main/java/org/apache/openejb/mockito/MockRegistry.java?rev=1383394&view=auto
==============================================================================
--- openejb/trunk/openejb/utils/openejb-mockito/src/main/java/org/apache/openejb/mockito/MockRegistry.java (added)
+++ openejb/trunk/openejb/utils/openejb-mockito/src/main/java/org/apache/openejb/mockito/MockRegistry.java Tue Sep 11 12:59:10 2012
@@ -0,0 +1,100 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.mockito;
+
+import org.apache.openejb.junit.TestInstance;
+import org.apache.openejb.loader.SystemInstance;
+import org.mockito.Mock;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * this class is used as a storage for mocks
+ * this logic could be enhanced but currently we store mock by types/name
+ *
+ * Note: only injected mocks are managed
+ */
+public class MockRegistry {
+ private static boolean initialized = false;
+ private static final Map<Class<?>, Object> mockInstancesByType = new HashMap<Class<?>, Object>();
+ private static final Map<String, Object> mockInstancesByName = new HashMap<String, Object>();
+
+ public static void reset() {
+ initialized = false;
+ mockInstancesByType.clear();
+ mockInstancesByName.clear();
+ }
+
+ public static Map<Class<?>, Object> mocksByType() {
+ ensureInit();
+ return mockInstancesByType;
+ }
+
+ public static Map<String, Object> mocksByName() {
+ ensureInit();
+ return mockInstancesByName;
+ }
+
+ private static void ensureInit() {
+ if (!initialized) {
+ synchronized (MockRegistry.class) {
+ if (!initialized) {
+ final TestInstance instance = SystemInstance.get().getComponent(TestInstance.class);
+ if (instance != null) {
+ Class<?> current = instance.getTestClass();
+ while (!current.equals(Object.class)) {
+ for (Field f : current.getDeclaredFields()) {
+ for (Annotation annotation : f.getAnnotations()) {
+ if (annotation.annotationType().getName().startsWith("org.mockito.")) {
+ final boolean acc = f.isAccessible();
+ try {
+ f.setAccessible(true);
+ final Object mockInstance = f.get(instance.getInstance());
+
+ if (Mock.class.equals(annotation.annotationType())) {
+ final Mock mock = (Mock) annotation;
+ if (!"".equals(mock.name())) {
+ mockInstancesByName.put(mock.name(), mockInstance);
+ } else {
+ mockInstancesByType.put(f.getType(), mockInstance);
+ }
+ } else {
+ mockInstancesByType.put(f.getType(), mockInstance);
+ }
+ } catch (IllegalAccessException e) {
+ // no-op
+ } finally {
+ f.setAccessible(acc);
+ }
+
+ break;
+ }
+ }
+ }
+
+ current = current.getSuperclass();
+ }
+ }
+ initialized = true;
+ }
+ }
+ }
+ }
+}
Added: openejb/trunk/openejb/utils/openejb-mockito/src/main/java/org/apache/openejb/mockito/MockitoExtension.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/utils/openejb-mockito/src/main/java/org/apache/openejb/mockito/MockitoExtension.java?rev=1383394&view=auto
==============================================================================
--- openejb/trunk/openejb/utils/openejb-mockito/src/main/java/org/apache/openejb/mockito/MockitoExtension.java (added)
+++ openejb/trunk/openejb/utils/openejb-mockito/src/main/java/org/apache/openejb/mockito/MockitoExtension.java Tue Sep 11 12:59:10 2012
@@ -0,0 +1,168 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.mockito;
+
+import org.apache.webbeans.annotation.AnyLiteral;
+import org.apache.webbeans.annotation.DefaultLiteral;
+import org.apache.webbeans.annotation.NamedLiteral;
+import org.mockito.cglib.proxy.Factory;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterBeanDiscovery;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.InjectionPoint;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * This class is responsible to add mocks as CDI beans.
+ */
+public class MockitoExtension implements Extension {
+ private static final Annotation DEFAULT_ANNOTATION = new DefaultLiteral();
+ private static final Annotation ANY_ANNOTATION = new AnyLiteral();
+
+ public void addMocks(@Observes final AfterBeanDiscovery abd) {
+ for (Map.Entry<Class<?>, Object> instance : MockRegistry.mocksByType().entrySet()) {
+ abd.addBean(new MockBean(instance.getKey(), instance.getValue()));
+ }
+ for (Map.Entry<String, Object> instance : MockRegistry.mocksByName().entrySet()) {
+ abd.addBean(new NamedMockBean(instance.getKey(), instance.getValue()));
+ }
+ }
+
+ private static class MockBean<T> implements Bean<T> {
+ protected static final Set<Annotation> QUALIFIERS = new HashSet<Annotation>(2) {{
+ add(DEFAULT_ANNOTATION);
+ add(ANY_ANNOTATION);
+ }};
+
+ protected final Class<T> clazz;
+ protected final Object instance;
+ protected final HashSet<Type> types;
+
+ public MockBean(final Class<T> key, final Object value) {
+ clazz = key;
+ instance = value;
+
+ types = new HashSet<Type>();
+ Class<?> current = clazz;
+ if (clazz != null) {
+ if (!Proxy.isProxyClass(current)) {
+ while (!Object.class.equals(current) && current != null) {
+ types.add(current);
+ current = current.getSuperclass();
+ }
+ }
+ for (Class<?> itf : clazz.getInterfaces()) {
+ if (Factory.class.isAssignableFrom(itf)) {
+ continue;
+ }
+
+ types.add(itf);
+ }
+ }
+ }
+
+ public Set<Type> getTypes() {
+ return types;
+ }
+
+ public Set<Annotation> getQualifiers() {
+ return QUALIFIERS;
+ }
+
+ public Class<? extends Annotation> getScope() {
+ return ApplicationScoped.class;
+ }
+
+ public String getName() {
+ return null;
+ }
+
+ public boolean isNullable() {
+ return false;
+ }
+
+ public Set<InjectionPoint> getInjectionPoints() {
+ return Collections.emptySet();
+ }
+
+ public Class<?> getBeanClass() {
+ return clazz;
+ }
+
+ public Set<Class<? extends Annotation>> getStereotypes() {
+ return Collections.emptySet();
+ }
+
+ public boolean isAlternative() {
+ return true;
+ }
+
+ public T create(final CreationalContext<T> context) {
+ return clazz.cast(instance);
+ }
+
+ public void destroy(final T instance, final CreationalContext<T> context) {
+ // no-op
+ }
+ }
+
+ private static class NamedMockBean<T> extends MockBean<T> {
+ private final String name;
+ private final Set<Annotation> qualifiers;
+
+ public NamedMockBean(final String named, final Object value) {
+ super((Class<T>) value.getClass(), value);
+
+ name = named;
+
+ // we need to pass value.getClass() to get interfaces
+ // but we don't want the proxy to be injectable
+ if (!clazz.isInterface()) {
+ types.remove(clazz);
+ }
+
+ qualifiers = new HashSet<Annotation>(2);
+ qualifiers.add(ANY_ANNOTATION);
+ qualifiers.add(new NamedLiteral(name));
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public Set<Annotation> getQualifiers() {
+ return qualifiers;
+ }
+
+ @Override
+ public T create(final CreationalContext<T> context) {
+ return clazz.cast(instance);
+ }
+ }
+}
Added: openejb/trunk/openejb/utils/openejb-mockito/src/main/java/org/apache/openejb/mockito/MockitoInjector.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/utils/openejb-mockito/src/main/java/org/apache/openejb/mockito/MockitoInjector.java?rev=1383394&view=auto
==============================================================================
--- openejb/trunk/openejb/utils/openejb-mockito/src/main/java/org/apache/openejb/mockito/MockitoInjector.java (added)
+++ openejb/trunk/openejb/utils/openejb-mockito/src/main/java/org/apache/openejb/mockito/MockitoInjector.java Tue Sep 11 12:59:10 2012
@@ -0,0 +1,48 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.mockito;
+
+import org.apache.openejb.Injection;
+import org.apache.openejb.injection.FallbackPropertyInjector;
+import org.apache.openejb.junit.TestInstance;
+import org.apache.openejb.loader.SystemInstance;
+import org.mockito.MockitoAnnotations;
+
+/**
+ * this class is instantiated when the FallbackPropertyInjector is set
+ * it is generally when the container is started
+ * it will reset mockito context (stored mocks) and do the mock injections in the test class
+ */
+public class MockitoInjector implements FallbackPropertyInjector {
+ public MockitoInjector() {
+ final Object instance = SystemInstance.get().getComponent(TestInstance.class).getInstance();
+ if (instance != null) {
+ MockitoAnnotations.initMocks(instance);
+ }
+ MockRegistry.reset();
+ }
+
+ @Override
+ public Object getValue(final Injection injection) {
+ try {
+ return MockRegistry.mocksByType()
+ .get(injection.getTarget().getDeclaredField(injection.getName()).getType());
+ } catch (Exception e) {
+ return MockRegistry.mocksByName().get(injection.getName());
+ }
+ }
+}
Added: openejb/trunk/openejb/utils/openejb-mockito/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/utils/openejb-mockito/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension?rev=1383394&view=auto
==============================================================================
--- openejb/trunk/openejb/utils/openejb-mockito/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension (added)
+++ openejb/trunk/openejb/utils/openejb-mockito/src/main/resources/META-INF/services/javax.enterprise.inject.spi.Extension Tue Sep 11 12:59:10 2012
@@ -0,0 +1 @@
+org.apache.openejb.mockito.MockitoExtension
Added: openejb/trunk/openejb/utils/openejb-mockito/src/test/java/org/apache/openejb/mockito/Facade.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/utils/openejb-mockito/src/test/java/org/apache/openejb/mockito/Facade.java?rev=1383394&view=auto
==============================================================================
--- openejb/trunk/openejb/utils/openejb-mockito/src/test/java/org/apache/openejb/mockito/Facade.java (added)
+++ openejb/trunk/openejb/utils/openejb-mockito/src/test/java/org/apache/openejb/mockito/Facade.java Tue Sep 11 12:59:10 2012
@@ -0,0 +1,49 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.mockito;
+
+import javax.ejb.EJB;
+import javax.ejb.Lock;
+import javax.ejb.LockType;
+import javax.ejb.Singleton;
+import javax.inject.Inject;
+import javax.inject.Named;
+
+@Singleton
+@Lock(LockType.READ)
+public class Facade {
+ @EJB
+ private Hello hello;
+
+ @Inject
+ private Hello helloCdi;
+
+ @Inject
+ @Named("named")
+ private Hello helloNamed;
+
+ public String hello() {
+ if (hello.id() != helloCdi.id()) {
+ throw new IllegalArgumentException();
+ }
+ return hello.hi();
+ }
+
+ public String name() {
+ return helloNamed.hi();
+ }
+}
Added: openejb/trunk/openejb/utils/openejb-mockito/src/test/java/org/apache/openejb/mockito/Hello.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/utils/openejb-mockito/src/test/java/org/apache/openejb/mockito/Hello.java?rev=1383394&view=auto
==============================================================================
--- openejb/trunk/openejb/utils/openejb-mockito/src/test/java/org/apache/openejb/mockito/Hello.java (added)
+++ openejb/trunk/openejb/utils/openejb-mockito/src/test/java/org/apache/openejb/mockito/Hello.java Tue Sep 11 12:59:10 2012
@@ -0,0 +1,22 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.mockito;
+
+public interface Hello {
+ String hi();
+ int id();
+}
Added: openejb/trunk/openejb/utils/openejb-mockito/src/test/java/org/apache/openejb/mockito/MockitoAndAppComposerTest.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/utils/openejb-mockito/src/test/java/org/apache/openejb/mockito/MockitoAndAppComposerTest.java?rev=1383394&view=auto
==============================================================================
--- openejb/trunk/openejb/utils/openejb-mockito/src/test/java/org/apache/openejb/mockito/MockitoAndAppComposerTest.java (added)
+++ openejb/trunk/openejb/utils/openejb-mockito/src/test/java/org/apache/openejb/mockito/MockitoAndAppComposerTest.java Tue Sep 11 12:59:10 2012
@@ -0,0 +1,73 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.openejb.mockito;
+
+import org.apache.openejb.junit.ApplicationComposer;
+import org.apache.openejb.junit.MockInjector;
+import org.apache.openejb.junit.Module;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+
+import javax.ejb.EJB;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.when;
+
+@RunWith(ApplicationComposer.class)
+public class MockitoAndAppComposerTest {
+ @EJB
+ private Facade facade;
+
+ @Mock
+ private Hello mock;
+
+ @Mock(name = "named")
+ private Hello named;
+
+ @MockInjector
+ public Class<?> mockitoInjector() {
+ return MockitoInjector.class;
+ }
+
+ @Module
+ public Class<?>[] classes() {
+ return new Class<?>[] { Hello.class, Facade.class };
+ }
+
+ @Test
+ public void testDefault() {
+ // play with mocks
+ when(mock.hi())
+ .thenReturn("openejb-mockito");
+ when(mock.id())
+ .thenReturn(12345);
+
+ // test
+ assertEquals("openejb-mockito", facade.hello());
+ }
+
+ @Test
+ public void testName() {
+ // play with mocks
+ when(named.hi())
+ .thenReturn("named");
+
+ // test
+ assertEquals("named", facade.name());
+ }
+}
Added: openejb/trunk/openejb/utils/openejb-mockito/src/test/resources/META-INF/beans.xml
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/utils/openejb-mockito/src/test/resources/META-INF/beans.xml?rev=1383394&view=auto
==============================================================================
--- openejb/trunk/openejb/utils/openejb-mockito/src/test/resources/META-INF/beans.xml (added)
+++ openejb/trunk/openejb/utils/openejb-mockito/src/test/resources/META-INF/beans.xml Tue Sep 11 12:59:10 2012
@@ -0,0 +1,18 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<beans />
Modified: openejb/trunk/openejb/utils/pom.xml
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb/utils/pom.xml?rev=1383394&r1=1383393&r2=1383394&view=diff
==============================================================================
--- openejb/trunk/openejb/utils/pom.xml (original)
+++ openejb/trunk/openejb/utils/pom.xml Tue Sep 11 12:59:10 2012
@@ -33,5 +33,6 @@
<module>openejb-spring</module>
<module>openejb-core-hibernate</module>
<module>openejb-provisionning</module>
+ <module>openejb-mockito</module>
</modules>
</project>