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>