Repository: weld/weld-junit (java)

Issue:
Swap master branch to CDI 2.0/Weld 3.1
We can make a branch with current state supporting multiversion (1.x branch) but master should move on to version 2.x and support CDI 2.0 and Weld3.x only.

This will in turn allows us to introduce new `MockBean` that will implement `Prioritized` hence making space for globally enabled alternatives (a problem discussed in #64). There will probably be another perks we can leverage in the code such as CDI configurators.

Pull request:
Swap master to CDI 2.0/Weld 3.1
Resolves #68 
Swaps versions and removes part of Travis Matrix.
~Introduces `AbstractMockBean` predecessor holding most of the logic which is then extended by `MockBean` and `MockBeanWithPriority`.~

~Currently, the idea is that `MockBeanWithPriority` is an always enabled alternative with default priority of 1 that can be changed.
I have done some reshuffling so that users cannot set this bean to `alternative=false` as it would only make the validations more complex because this bean `implements Prioritized` and is specifically designed to allow for globally enabled mocked alternatives.~

The builder on `MockBean` now allows to set a priority and if done, we will instantiate `MockBeanWithPriority` implementing `Prioritized` instead of standard `MockBean`.

I'll look for some other bits of code that could be improved with CDI 2.0 approach...

Patch:
diff --git a/.travis.yml b/.travis.yml
index 01cc7e7..e4bf80f 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,8 +2,5 @@ language: java
 jdk:
   - oraclejdk8
   - openjdk8
-env:
-  - WELD_JUNIT_PROFILE=weld2
-  - WELD_JUNIT_PROFILE=weld3
 script: "WELD_JUNIT_DEBUG=spotbugs mvn verify -Dspotbugs.failOnError=true"
 sudo: false
diff --git a/junit-common/pom.xml b/junit-common/pom.xml
index f76f23d..78bc236 100644
--- a/junit-common/pom.xml
+++ b/junit-common/pom.xml
@@ -4,7 +4,7 @@
    <parent>
       <groupId>org.jboss.weld</groupId>
       <artifactId>weld-junit-parent</artifactId>
-      <version>1.3.2-SNAPSHOT</version>
+      <version>2.0.0-SNAPSHOT</version>
    </parent>
 
    <artifactId>weld-junit-common</artifactId>
diff --git a/junit-common/src/main/java/org/jboss/weld/junit/ContextImpl.java b/junit-common/src/main/java/org/jboss/weld/junit/ContextImpl.java
index 229d98a..dd19df7 100644
--- a/junit-common/src/main/java/org/jboss/weld/junit/ContextImpl.java
+++ b/junit-common/src/main/java/org/jboss/weld/junit/ContextImpl.java
@@ -22,6 +22,8 @@ import java.util.Map;
 import java.util.logging.Logger;
 
 import javax.enterprise.context.ContextNotActiveException;
+import javax.enterprise.context.Destroyed;
+import javax.enterprise.context.Initialized;
 import javax.enterprise.context.spi.Context;
 import javax.enterprise.context.spi.Contextual;
 import javax.enterprise.context.spi.CreationalContext;
@@ -88,7 +90,7 @@ class ContextImpl implements Context {
 
     public void activate() {
         currentContext.set(new HashMap<Contextual<?>, ContextualInstance<?>>());
-        beanManager.fireEvent(new Object(), InitializedLiteral.of(scope));
+        beanManager.fireEvent(new Object(), Initialized.Literal.of(scope));
     }
 
     public void deactivate() {
@@ -105,7 +107,7 @@ class ContextImpl implements Context {
         }
         ctx.clear();
         currentContext.remove();
-        beanManager.fireEvent(new Object(), DestroyedLiteral.of(scope));
+        beanManager.fireEvent(new Object(), Destroyed.Literal.of(scope));
     }
 
     /**
diff --git a/junit-common/src/main/java/org/jboss/weld/junit/DestroyedLiteral.java b/junit-common/src/main/java/org/jboss/weld/junit/DestroyedLiteral.java
deleted file mode 100644
index a3fddc7..0000000
--- a/junit-common/src/main/java/org/jboss/weld/junit/DestroyedLiteral.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2018, Red Hat, Inc., and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * Licensed 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.jboss.weld.junit;
-
-import java.lang.annotation.Annotation;
-
-import javax.enterprise.context.Destroyed;
-import javax.enterprise.util.AnnotationLiteral;
-
-/**
- * Supports inline instantiation of the {@link Destroyed} qualifier.
- *
- * @author Martin Kouba
- */
-class DestroyedLiteral extends AnnotationLiteral<Destroyed> implements Destroyed {
-
-    private static final long serialVersionUID = 1L;
-
-    private final Class<? extends Annotation> value;
-
-    public static DestroyedLiteral of(Class<? extends Annotation> value) {
-        return new DestroyedLiteral(value);
-    }
-
-    private DestroyedLiteral(Class<? extends Annotation> value) {
-        this.value = value;
-    }
-
-    public Class<? extends Annotation> value() {
-        return value;
-    }
-}
diff --git a/junit-common/src/main/java/org/jboss/weld/junit/InitializedLiteral.java b/junit-common/src/main/java/org/jboss/weld/junit/InitializedLiteral.java
deleted file mode 100644
index 7e9e7b5..0000000
--- a/junit-common/src/main/java/org/jboss/weld/junit/InitializedLiteral.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2018, Red Hat, Inc., and individual contributors
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * Licensed 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.jboss.weld.junit;
-
-import java.lang.annotation.Annotation;
-
-import javax.enterprise.context.Initialized;
-import javax.enterprise.util.AnnotationLiteral;
-
-/**
- * Supports inline instantiation of the {@link Initialized} qualifier.
- *
- * @author Martin Kouba
- */
-class InitializedLiteral extends AnnotationLiteral<Initialized> implements Initialized {
-
-    private static final long serialVersionUID = 1L;
-
-    private final Class<? extends Annotation> value;
-
-    public static InitializedLiteral of(Class<? extends Annotation> value) {
-        return new InitializedLiteral(value);
-    }
-
-    private InitializedLiteral(Class<? extends Annotation> value) {
-        this.value = value;
-    }
-
-    public Class<? extends Annotation> value() {
-        return value;
-    }
-}
diff --git a/junit-common/src/main/java/org/jboss/weld/junit/MockBean.java b/junit-common/src/main/java/org/jboss/weld/junit/MockBean.java
index f46b1b3..24a0e68 100644
--- a/junit-common/src/main/java/org/jboss/weld/junit/MockBean.java
+++ b/junit-common/src/main/java/org/jboss/weld/junit/MockBean.java
@@ -36,6 +36,7 @@ import javax.enterprise.inject.Stereotype;
 import javax.enterprise.inject.spi.Bean;
 import javax.enterprise.inject.spi.InjectionPoint;
 import javax.enterprise.inject.spi.PassivationCapable;
+import javax.enterprise.inject.spi.Prioritized;
 import javax.enterprise.inject.spi.Unmanaged;
 import javax.enterprise.inject.spi.Unmanaged.UnmanagedInstance;
 import javax.enterprise.util.AnnotationLiteral;
@@ -136,7 +137,7 @@ public class MockBean<T> implements Bean<T>, PassivationCapable {
 
     private final Class<?> beanClass;
 
-    private MockBean(Class<?> beanClass, Set<Class<? extends Annotation>> stereotypes, boolean alternative, boolean selectForSyntheticBeanArchive, String name,
+    protected MockBean(Class<?> beanClass, Set<Class<? extends Annotation>> stereotypes, boolean alternative, boolean selectForSyntheticBeanArchive, String name,
             Set<Annotation> qualifiers, Set<Type> types, Class<? extends Annotation> scope, CreateFunction<T> createCallback,
             DestroyFunction<T> destroyCallback) {
         this.beanClass = beanClass;
@@ -325,6 +326,8 @@ public class MockBean<T> implements Bean<T>, PassivationCapable {
 
         private boolean selectForSyntheticBeanArchive;
 
+        private Integer priority;
+
         private String name;
 
         private Set<Annotation> qualifiers;
@@ -346,6 +349,7 @@ public class MockBean<T> implements Bean<T>, PassivationCapable {
             this.types = new HashSet<>();
             this.types.add(Object.class);
             this.beanClass = WeldCDIExtension.class;
+            this.priority = null;
         }
 
         /**
@@ -447,6 +451,32 @@ public class MockBean<T> implements Bean<T>, PassivationCapable {
             return this;
         }
 
+        /**
+         * Programmatic equivalent to to putting {@link javax.annotation.Priority} annotation on a bean class.
+         * Allows for globally enabled alternatives.
+         *
+         * @param priority
+         * @return self
+         * @see Prioritized#getPriority()
+         */
+        public Builder<T> priority(int priority) {
+            this.priority = priority;
+            return this;
+        }
+
+        /**
+         * This beans is a globally enabled alternative with a priority equal to its method parameter.
+         * Calling this method is a shortcut for {@link Builder#priority(int)} and {@link Builder#alternative(boolean)}
+         *
+         * @param priority
+         * @return self
+         */
+        public Builder<T> globallySelectedAlternative(int priority) {
+            this.priority = priority;
+            this.alternative = true;
+            return this;
+        }
+
         /**
          * The bean is an alternative and should be automatically selected for the synthetic bean archive.
          *
@@ -455,7 +485,6 @@ public class MockBean<T> implements Bean<T>, PassivationCapable {
          * selected for a bean archive. By default, all mock beans share the same bean class - {@code org.jboss.weld.junit.WeldCDIExtension}.
          * </p>
          *
-         * @param value
          * @return self
          * @see Bean#isAlternative()
          * @see Weld#addAlternative(Class)
@@ -496,7 +525,7 @@ public class MockBean<T> implements Bean<T>, PassivationCapable {
 
         /**
          *
-         * @param qualifier
+         * @param stereotype
          * @return self
          */
         public Builder<T> addStereotype(Class<? extends Annotation> stereotype) {
@@ -594,8 +623,14 @@ public class MockBean<T> implements Bean<T>, PassivationCapable {
                     }
                 }
             }
-            return new MockBean<>(beanClass, stereotypes, alternative, selectForSyntheticBeanArchive, name, qualifiers, types, scope, createCallback,
-                    destroyCallback);
+            // if given any priority, we will instead initialize MockBeanWithPriority
+            if (priority != null) {
+                return new MockBeanWithPriority<>(beanClass, stereotypes, alternative, selectForSyntheticBeanArchive, priority, name, qualifiers, types, scope, createCallback,
+                        destroyCallback);
+            } else {
+                return new MockBean<>(beanClass, stereotypes, alternative, selectForSyntheticBeanArchive, name, qualifiers, types, scope, createCallback,
+                        destroyCallback);
+            }
         }
 
     }
diff --git a/junit-common/src/main/java/org/jboss/weld/junit/MockBeanWithPriority.java b/junit-common/src/main/java/org/jboss/weld/junit/MockBeanWithPriority.java
new file mode 100644
index 0000000..6aca6ff
--- /dev/null
+++ b/junit-common/src/main/java/org/jboss/weld/junit/MockBeanWithPriority.java
@@ -0,0 +1,33 @@
+package org.jboss.weld.junit;
+
+import javax.enterprise.inject.spi.Prioritized;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Set;
+
+/**
+ * A subclass of {@link MockBean} implementing {@link Prioritized} hence allowing for globally enabled alternatives.
+ * Used instead of {@link MockBean} if user specified {@link MockBean.Builder#priority(int)}.
+ *
+ * @author Matej Novotny
+ */
+class MockBeanWithPriority<T> extends MockBean<T> implements Prioritized {
+
+    private final int priority;
+
+    MockBeanWithPriority(Class<?> beanClass, Set<Class<? extends Annotation>> stereotypes, boolean alternative,
+                                 boolean selectForSyntheticBeanArchive, int priority, String name,
+                                 Set<Annotation> qualifiers, Set<Type> types, Class<? extends Annotation> scope,
+                                 CreateFunction<T> createCallback, DestroyFunction<T> destroyCallback) {
+        super(beanClass, stereotypes, alternative, selectForSyntheticBeanArchive, name, qualifiers, types, scope, createCallback, destroyCallback);
+        if (priority <= 0) {
+            throw new IllegalArgumentException("MockBean cannot have priority equal or lower than 0!");
+        }
+        this.priority = priority;
+    }
+
+    @Override
+    public int getPriority() {
+        return this.priority;
+    }
+}
diff --git a/junit-common/src/main/java/org/jboss/weld/junit/MockEjbInjectionServices.java b/junit-common/src/main/java/org/jboss/weld/junit/MockEjbInjectionServices.java
index be0027b..4a36e8f 100644
--- a/junit-common/src/main/java/org/jboss/weld/junit/MockEjbInjectionServices.java
+++ b/junit-common/src/main/java/org/jboss/weld/junit/MockEjbInjectionServices.java
@@ -48,14 +48,9 @@ public class MockEjbInjectionServices implements EjbInjectionServices {
         return new ResourceReferenceFactory<Object>() {
             @Override
             public ResourceReference<Object> createResource() {
-                return new SimpleResourceReference<Object>(resolveEjb(injectionPoint));
+                return new SimpleResourceReference<Object>(ejbFactory.apply(injectionPoint));
             }
         };
     }
 
-    // only for Weld 2
-    public Object resolveEjb(InjectionPoint injectionPoint) {
-        return ejbFactory.apply(injectionPoint);
-    }
-
 }
diff --git a/junit-common/src/main/java/org/jboss/weld/junit/MockJpaInjectionServices.java b/junit-common/src/main/java/org/jboss/weld/junit/MockJpaInjectionServices.java
index 2167916..6a78dc1 100644
--- a/junit-common/src/main/java/org/jboss/weld/junit/MockJpaInjectionServices.java
+++ b/junit-common/src/main/java/org/jboss/weld/junit/MockJpaInjectionServices.java
@@ -49,7 +49,14 @@ public class MockJpaInjectionServices implements JpaInjectionServices {
         return new ResourceReferenceFactory<EntityManager>() {
             @Override
             public ResourceReference<EntityManager> createResource() {
-                return new SimpleResourceReference<EntityManager>(resolvePersistenceContext(injectionPoint));
+                if (persistenceContextFactory == null) {
+                    throw new IllegalStateException("Persistent context factory not set, cannot resolve injection point: " + injectionPoint);
+                }
+                Object context = persistenceContextFactory.apply(injectionPoint);
+                if (context == null || context instanceof EntityManager) {
+                    return new SimpleResourceReference<EntityManager>((EntityManager) context);
+                }
+                throw new IllegalStateException("Not an EntityManager instance: " + context);
             }
         };
     }
@@ -59,35 +66,18 @@ public class MockJpaInjectionServices implements JpaInjectionServices {
         return new ResourceReferenceFactory<EntityManagerFactory>() {
             @Override
             public ResourceReference<EntityManagerFactory> createResource() {
-                return new SimpleResourceReference<EntityManagerFactory>(resolvePersistenceUnit(injectionPoint));
+                if (persistenceUnitFactory == null) {
+                    throw new IllegalStateException("Persistent unit factory not set, cannot resolve injection point: " + injectionPoint);
+                }
+                Object unit = persistenceUnitFactory.apply(injectionPoint);
+                if (unit == null || unit instanceof EntityManagerFactory) {
+                    return new SimpleResourceReference<EntityManagerFactory>((EntityManagerFactory) unit);
+                }
+                throw new IllegalStateException("Not an EntityManagerFactory instance: " + unit);
             }
         };
     }
 
-    // only for Weld 2
-    public EntityManager resolvePersistenceContext(InjectionPoint injectionPoint) {
-        if (persistenceContextFactory == null) {
-            throw new IllegalStateException("Persistent context factory not set, cannot resolve injection point: " + injectionPoint);
-        }
-        Object context = persistenceContextFactory.apply(injectionPoint);
-        if (context == null || context instanceof EntityManager) {
-            return (EntityManager) context;
-        }
-        throw new IllegalStateException("Not an EntityManager instance: " + context);
-    }
-
-    // only for Weld 2
-    public EntityManagerFactory resolvePersistenceUnit(InjectionPoint injectionPoint) {
-        if (persistenceUnitFactory == null) {
-            throw new IllegalStateException("Persistent unit factory not set, cannot resolve injection point: " + injectionPoint);
-        }
-        Object unit = persistenceUnitFactory.apply(injectionPoint);
-        if (unit == null || unit instanceof EntityManagerFactory) {
-            return (EntityManagerFactory) unit;
-        }
-        throw new IllegalStateException("Not an EntityManagerFactory instance: " + unit);
-    }
-
     @Override
     public void cleanup() {
     }
diff --git a/junit-common/src/main/java/org/jboss/weld/junit/MockResourceInjectionServices.java b/junit-common/src/main/java/org/jboss/weld/junit/MockResourceInjectionServices.java
index 2b28456..ecbe444 100644
--- a/junit-common/src/main/java/org/jboss/weld/junit/MockResourceInjectionServices.java
+++ b/junit-common/src/main/java/org/jboss/weld/junit/MockResourceInjectionServices.java
@@ -49,8 +49,7 @@ public class MockResourceInjectionServices implements ResourceInjectionServices
         this.resources = ImmutableMap.copyOf(resources);
     }
 
-    // only for Weld 2
-    public Object resolveResource(InjectionPoint injectionPoint) {
+    private Object resolveResource(InjectionPoint injectionPoint) {
         Resource resource = getResourceAnnotation(injectionPoint);
         if (resource == null) {
             throw new IllegalArgumentException("No @Resource annotation found on " + injectionPoint);
@@ -83,11 +82,6 @@ public class MockResourceInjectionServices implements ResourceInjectionServices
         throw new UnsupportedOperationException();
     }
 
-    // only for Weld 2
-    public Object resolveResource(String jndiName, String mappedName) {
-        throw new UnsupportedOperationException();
-    }
-
     @Override
     public void cleanup() {
     }
diff --git a/junit4/pom.xml b/junit4/pom.xml
index b584bea..370c8e4 100644
--- a/junit4/pom.xml
+++ b/junit4/pom.xml
@@ -4,7 +4,7 @@
    <parent>
       <groupId>org.jboss.weld</groupId>
       <artifactId>weld-junit-parent</artifactId>
-      <version>1.3.2-SNAPSHOT</version>
+      <version>2.0.0-SNAPSHOT</version>
    </parent>
 
    <artifactId>weld-junit4</artifactId>
@@ -43,29 +43,13 @@
          <scope>test</scope>
       </dependency>
 
-   </dependencies>
-
-   <profiles>
-
-      <profile>
-         <id>weld3</id>
-         <activation>
-            <activeByDefault>false</activeByDefault>
-            <property>
-               <name>env.WELD_JUNIT_PROFILE</name>
-               <value>weld3</value>
-            </property>
-         </activation>
-         <dependencies>
-            <dependency>
-               <groupId>org.jboss.weld.module</groupId>
-               <artifactId>weld-ejb</artifactId>
-               <version>${version.weld}</version>
-               <scope>test</scope>
-            </dependency>
-         </dependencies>
-      </profile>
+      <dependency>
+         <groupId>org.jboss.weld.module</groupId>
+         <artifactId>weld-ejb</artifactId>
+         <version>${version.weld}</version>
+         <scope>test</scope>
+      </dependency>
 
-   </profiles>
+   </dependencies>
 
 </project>
diff --git a/junit5/pom.xml b/junit5/pom.xml
index 05454c8..bcda77c 100644
--- a/junit5/pom.xml
+++ b/junit5/pom.xml
@@ -5,7 +5,7 @@
    <parent>
       <groupId>org.jboss.weld</groupId>
       <artifactId>weld-junit-parent</artifactId>
-      <version>1.3.2-SNAPSHOT</version>
+      <version>2.0.0-SNAPSHOT</version>
    </parent>
 
    <artifactId>weld-junit5</artifactId>
@@ -48,30 +48,14 @@
          <artifactId>hibernate-jpa-2.1-api</artifactId>
          <scope>test</scope>
       </dependency>
+
+      <dependency>
+         <groupId>org.jboss.weld.module</groupId>
+         <artifactId>weld-ejb</artifactId>
+         <version>${version.weld}</version>
+         <scope>test</scope>
+      </dependency>
       
    </dependencies>
 
-   <profiles>
-
-      <profile>
-         <id>weld3</id>
-         <activation>
-            <activeByDefault>false</activeByDefault>
-            <property>
-               <name>env.WELD_JUNIT_PROFILE</name>
-               <value>weld3</value>
-            </property>
-         </activation>
-         <dependencies>
-            <dependency>
-               <groupId>org.jboss.weld.module</groupId>
-               <artifactId>weld-ejb</artifactId>
-               <version>${version.weld}</version>
-               <scope>test</scope>
-            </dependency>
-         </dependencies>
-      </profile>
-
-   </profiles>
-
 </project>
diff --git a/pom.xml b/pom.xml
index 770182c..a94d891 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,7 +2,7 @@
    <modelVersion>4.0.0</modelVersion>
    <artifactId>weld-junit-parent</artifactId>
    <packaging>pom</packaging>
-   <version>1.3.2-SNAPSHOT</version>
+   <version>2.0.0-SNAPSHOT</version>
 
    <name>Weld JUnit Extensions</name>
    <description>Set of JUnit extensions to enhance the testing of CDI components.</description>
@@ -42,8 +42,7 @@
       <!-- Versions -->
       <version.junit4>4.12</version.junit4>
       <version.junit.jupiter>5.4.1</version.junit.jupiter>
-      <version.weld>2.4.8.Final</version.weld>
-      <version.weld3>3.1.0.Final</version.weld3>
+      <version.weld>3.1.0.Final</version.weld>
       <version.mockito>2.25.1</version.mockito>
       <version.jboss-ejb-api>1.0.0.Final</version.jboss-ejb-api>
       <version.hibernate-jpa-api>1.0.0.Final</version.hibernate-jpa-api>
@@ -126,19 +125,6 @@
    </dependencyManagement>
 
    <profiles>
-       <profile>
-           <id>weld3</id>
-           <activation>
-               <activeByDefault>false</activeByDefault>
-               <property>
-                   <name>env.WELD_JUNIT_PROFILE</name>
-                   <value>weld3</value>
-               </property>
-           </activation>
-           <properties>
-               <version.weld>${version.weld3}</version.weld>
-           </properties>
-       </profile>
        <profile>
            <id>spotbugs</id>
            <activation>


Test patch:
diff --git a/junit4/src/test/java/org/jboss/weld/junit4/bean/AddGloballyEnabledAlternativeTest.java b/junit4/src/test/java/org/jboss/weld/junit4/bean/AddGloballyEnabledAlternativeTest.java
new file mode 100644
index 0000000..6ad149a
--- /dev/null
+++ b/junit4/src/test/java/org/jboss/weld/junit4/bean/AddGloballyEnabledAlternativeTest.java
@@ -0,0 +1,63 @@
+package org.jboss.weld.junit4.bean;
+
+import org.jboss.weld.junit.MockBean;
+import org.jboss.weld.junit4.WeldInitiator;
+import org.junit.Assert;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.util.TypeLiteral;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Tests {@link org.jboss.weld.junit.MockBean} adding a bean that is a globally enabled alternative.
+ *
+ * @author Matej Novotny
+ */
+public class AddGloballyEnabledAlternativeTest {
+    
+    @Rule
+    public WeldInitiator weld = WeldInitiator.from(Bar.class)
+            .addBeans(createFooAlternativeBean(), createListBean())
+            .build();
+
+    public static Bean<?> createFooAlternativeBean() {
+        return MockBean.read(Foo.class)
+                .priority(3)
+                .alternative(true)
+                .addQualifier(Meaty.Literal.INSTANCE)
+                .build();
+    }
+
+    static Bean<?> createListBean() {
+        return MockBean.builder()
+                .types(new TypeLiteral<List<String>>() {
+                }.getType())
+                .globallySelectedAlternative(2)
+                .creating(
+                        // Mock object provided by Mockito
+                        Mockito.when(Mockito.mock(List.class).get(0)).thenReturn("42").getMock())
+                .build();
+    }
+
+    @Test
+    public void testAllBeansAreAddedAndCanBeSelected() {
+        Bar bar = weld.select(Bar.class).get();
+        Assert.assertNotNull(bar.getFoo());
+        Assert.assertNotNull(bar.getSomeList());
+        Assert.assertEquals("42", bar.getSomeList().get(0));
+
+        // assert all of these are actually alternatives (enabled)
+        Set<Bean<?>> beans = weld.getBeanManager().getBeans(Foo.class, Meaty.Literal.INSTANCE);
+        Assert.assertEquals(1, beans.size());
+        Assert.assertTrue(beans.iterator().next().isAlternative());
+
+        beans = weld.getBeanManager().getBeans(new TypeLiteral<List<String>>() {
+        }.getType());
+        Assert.assertEquals(1, beans.size());
+        Assert.assertTrue(beans.iterator().next().isAlternative());
+    }
+}
diff --git a/junit4/src/test/java/org/jboss/weld/junit4/bean/Bar.java b/junit4/src/test/java/org/jboss/weld/junit4/bean/Bar.java
new file mode 100644
index 0000000..84ba4b6
--- /dev/null
+++ b/junit4/src/test/java/org/jboss/weld/junit4/bean/Bar.java
@@ -0,0 +1,23 @@
+package org.jboss.weld.junit4.bean;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import java.util.List;
+
+@ApplicationScoped
+public class Bar {
+    @Inject
+    @Meaty
+    private Foo foo;
+
+    @Inject
+    private List<String> someList;
+
+    public List<String> getSomeList() {
+        return someList;
+    }
+
+    public Foo getFoo() {
+        return foo;
+    }
+}
diff --git a/junit4/src/test/java/org/jboss/weld/junit4/bean/Foo.java b/junit4/src/test/java/org/jboss/weld/junit4/bean/Foo.java
new file mode 100644
index 0000000..436638c
--- /dev/null
+++ b/junit4/src/test/java/org/jboss/weld/junit4/bean/Foo.java
@@ -0,0 +1,7 @@
+package org.jboss.weld.junit4.bean;
+
+public class Foo {
+    public String ping() {
+        return "foo";
+    }
+}
diff --git a/junit5/src/test/java/org/jboss/weld/junit5/bean/AddGloballyEnabledAlternativeTest.java b/junit5/src/test/java/org/jboss/weld/junit5/bean/AddGloballyEnabledAlternativeTest.java
new file mode 100644
index 0000000..4435206
--- /dev/null
+++ b/junit5/src/test/java/org/jboss/weld/junit5/bean/AddGloballyEnabledAlternativeTest.java
@@ -0,0 +1,66 @@
+package org.jboss.weld.junit5.bean;
+
+import org.jboss.weld.junit.MockBean;
+import org.jboss.weld.junit5.WeldInitiator;
+import org.jboss.weld.junit5.WeldJunit5Extension;
+import org.jboss.weld.junit5.WeldSetup;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.ExtendWith;
+import org.mockito.Mockito;
+
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.util.TypeLiteral;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Tests {@link org.jboss.weld.junit.MockBean} adding a bean that is a globally enabled alternative.
+ *
+ * @author Matej Novotny
+ */
+@ExtendWith(WeldJunit5Extension.class)
+public class AddGloballyEnabledAlternativeTest {
+
+    @WeldSetup
+    public WeldInitiator weld = WeldInitiator.from(Bar.class)
+            .addBeans(createFooAlternativeBean(), createListBean())
+            .build();
+
+    public static Bean<?> createFooAlternativeBean(){
+        return MockBean.read(Foo.class)
+                .priority(3)
+                .alternative(true)
+                .addQualifier(Meaty.Literal.INSTANCE)
+                .build();
+    }
+
+    static Bean<?> createListBean() {
+        return MockBean.builder()
+                .types(new TypeLiteral<List<String>>() {
+                }.getType())
+                .globallySelectedAlternative(2)
+                .creating(
+                        // Mock object provided by Mockito
+                        Mockito.when(Mockito.mock(List.class).get(0)).thenReturn("42").getMock())
+                .build();
+    }
+
+    @Test
+    public void testAllBeansAreAddedAndCanBeSelected() {
+        Bar bar = weld.select(Bar.class).get();
+        Assertions.assertNotNull(bar.getFoo());
+        Assertions.assertNotNull(bar.getSomeList());
+        Assertions.assertEquals("42", bar.getSomeList().get(0));
+
+        // assert all of these are actually alternatives (enabled)
+        Set<Bean<?>> beans = weld.getBeanManager().getBeans(Foo.class, Meaty.Literal.INSTANCE);
+        Assertions.assertEquals(1, beans.size());
+        Assertions.assertTrue(beans.iterator().next().isAlternative());
+
+        beans = weld.getBeanManager().getBeans(new TypeLiteral<List<String>>(){}.getType());
+        Assertions.assertEquals(1, beans.size());
+        Assertions.assertTrue(beans.iterator().next().isAlternative());
+    }
+}
diff --git a/junit5/src/test/java/org/jboss/weld/junit5/bean/Bar.java b/junit5/src/test/java/org/jboss/weld/junit5/bean/Bar.java
new file mode 100644
index 0000000..b3b7e9a
--- /dev/null
+++ b/junit5/src/test/java/org/jboss/weld/junit5/bean/Bar.java
@@ -0,0 +1,24 @@
+package org.jboss.weld.junit5.bean;
+
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import java.util.List;
+
+@ApplicationScoped
+public class Bar {
+
+    @Inject
+    @Meaty
+    private Foo foo;
+
+    @Inject
+    private List<String> someList;
+
+    public List<String> getSomeList() {
+        return someList;
+    }
+
+    public Foo getFoo() {
+        return foo;
+    }
+}
diff --git a/junit5/src/test/java/org/jboss/weld/junit5/bean/Foo.java b/junit5/src/test/java/org/jboss/weld/junit5/bean/Foo.java
new file mode 100644
index 0000000..2032697
--- /dev/null
+++ b/junit5/src/test/java/org/jboss/weld/junit5/bean/Foo.java
@@ -0,0 +1,8 @@
+package org.jboss.weld.junit5.bean;
+
+public class Foo {
+
+    public String ping() {
+        return "foo";
+    }
+}