Repository: weld/weld-junit (java)

Issue:
Introduce mock interceptor
I think it might be useful to add a **mock** interceptor programatically (similarly to https://github.com/weld/api/blob/master/weld/src/main/java/org/jboss/weld/bootstrap/event/InterceptorConfigurator.java), e.g.:

````java
WeldInitiator.from(Foo.class).addBeans(
   MockInterceptor.withBindings(FooBinding.Literal.INSTANCE).aroundInvoke((ctx, interceptedBean) -> {
                return ctx.proceed();
                })).build();
````

Pull request description:
Introduce mock interceptors
- resolves #26

Patch:
diff --git a/junit-common/src/main/java/org/jboss/weld/junit/AbstractWeldInitiator.java b/junit-common/src/main/java/org/jboss/weld/junit/AbstractWeldInitiator.java
index 30577e9..fc5c385 100644
--- a/junit-common/src/main/java/org/jboss/weld/junit/AbstractWeldInitiator.java
+++ b/junit-common/src/main/java/org/jboss/weld/junit/AbstractWeldInitiator.java
@@ -98,6 +98,7 @@ public abstract class AbstractWeldInitiator implements Instance<Object>, Contain
         this.scopesToActivate = scopesToActivate;
         this.beans = beans;
         this.weld = weld;
+        boolean hasMockInterceptor = false;
         if (hasScopesToActivate() || hasBeansToAdd()) {
             this.extension = new WeldCDIExtension(this.scopesToActivate, this.beans);
             for (Bean<?> bean : this.beans) {
@@ -106,8 +107,14 @@ public abstract class AbstractWeldInitiator implements Instance<Object>, Contain
                     if (mockBean.isAlternative() && mockBean.isSelectForSyntheticBeanArchive()) {
                         this.weld.addAlternative(mockBean.getBeanClass());
                     }
+                } else if (bean instanceof MockInterceptor && ((MockInterceptor) bean).hasDefaultBeanClass()) {
+                    hasMockInterceptor = true;
                 }
             }
+            // Automatically enable all mock interceptors for the synthetic bean archive
+            if (hasMockInterceptor) {
+                this.weld.addInterceptor(MockInterceptor.class);
+            }
             this.weld.addExtension(this.extension);
         } else {
             this.extension = null;
@@ -373,6 +380,8 @@ public abstract class AbstractWeldInitiator implements Instance<Object>, Contain
          * @param beans
          * @return self
          * @see AfterBeanDiscovery#addBean(Bean)
+         * @see MockBean
+         * @see MockInterceptor
          * @since 1.1
          */
         public T addBeans(Bean<?>... beans) {
diff --git a/junit-common/src/main/java/org/jboss/weld/junit/MockInterceptor.java b/junit-common/src/main/java/org/jboss/weld/junit/MockInterceptor.java
new file mode 100644
index 0000000..b02805e
--- /dev/null
+++ b/junit-common/src/main/java/org/jboss/weld/junit/MockInterceptor.java
@@ -0,0 +1,304 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2017, 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.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+import javax.enterprise.context.Dependent;
+import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.CDI;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.InterceptionType;
+import javax.enterprise.inject.spi.Interceptor;
+import javax.interceptor.InvocationContext;
+
+import org.jboss.weld.bean.builtin.BeanManagerProxy;
+import org.jboss.weld.junit.MockInterceptor.MockInterceptorInstance;
+import org.jboss.weld.util.bean.SerializableForwardingBean;
+
+/**
+ * This custom {@link Interceptor} implementation is useful for mocking.
+ * <p>
+ * A new instance is usually created through a {@link Builder} (see also {@link #withBindings(Annotation...)} method) and then passed to the
+ * {@link WeldInitiator.Builder#addBeans(Bean...)} method.
+ * </p>
+ * <p>
+ * Note that by default all mock interceptors are automatically enabled for the synthetic bean archive. If needed a custom bean class can be set through the
+ * {@link Builder#beanClass(Class)} method - the bean class can be used to enable the interceptor for a bean archive. It's not possible to enable a mock
+ * interceptor globally (per application).
+ * </p>
+ *
+ * @author Martin Kouba
+ * @see WeldInitiator.Builder#addBean(Bean)
+ * @since 1.2.1
+ */
+public class MockInterceptor implements Interceptor<MockInterceptorInstance> {
+
+    /**
+     *
+     * @param interceptorBindings
+     * @return a new builder instance with the specified interceptor bindings
+     */
+    public static Builder withBindings(Annotation... interceptorBindings) {
+        return new Builder().bindings(interceptorBindings);
+    }
+
+    private final Class<?> beanClass;
+
+    private final InterceptionType type;
+
+    private final InterceptionCallback callback;
+
+    private final Set<Annotation> interceptorBindings;
+
+    /**
+     *
+     * @param beanClass
+     * @param type
+     * @param callback
+     * @param interceptorBindings
+     */
+    private MockInterceptor(Class<?> beanClass, InterceptionType type, InterceptionCallback callback, Set<Annotation> interceptorBindings) {
+        this.beanClass = beanClass;
+        this.type = type;
+        this.callback = callback;
+        this.interceptorBindings = interceptorBindings;
+    }
+
+    @Override
+    public Set<Annotation> getInterceptorBindings() {
+        return interceptorBindings;
+    }
+
+    @Override
+    public boolean intercepts(InterceptionType type) {
+        return this.type.equals(type);
+    }
+
+    @Override
+    public Object intercept(InterceptionType type, MockInterceptorInstance instance, InvocationContext ctx) throws Exception {
+        return callback.invoke(ctx, instance.getInterceptedBean());
+    }
+
+    @Override
+    public MockInterceptorInstance create(CreationalContext<MockInterceptorInstance> creationalContext) {
+        return new MockInterceptorInstance(getInterceptedBean(creationalContext), BeanManagerProxy.unwrap(CDI.current().getBeanManager()).getContextId());
+    }
+
+    @Override
+    public void destroy(MockInterceptorInstance instance, CreationalContext<MockInterceptorInstance> creationalContext) {
+        // No-op
+    }
+
+    @Override
+    public Class<?> getBeanClass() {
+        return beanClass;
+    }
+
+    @Override
+    public Set<InjectionPoint> getInjectionPoints() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public boolean isNullable() {
+        return false;
+    }
+
+    @Override
+    public Set<Type> getTypes() {
+        return Collections.singleton(Object.class);
+    }
+
+    @Override
+    public Set<Annotation> getQualifiers() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public Class<? extends Annotation> getScope() {
+        return Dependent.class;
+    }
+
+    @Override
+    public String getName() {
+        return null;
+    }
+
+    @Override
+    public Set<Class<? extends Annotation>> getStereotypes() {
+        return Collections.emptySet();
+    }
+
+    @Override
+    public boolean isAlternative() {
+        return false;
+    }
+
+    boolean hasDefaultBeanClass() {
+        return MockInterceptor.class.equals(beanClass);
+    }
+
+    private Bean<?> getInterceptedBean(CreationalContext<MockInterceptorInstance> ctx) {
+        if (!ctx.getClass().getName().startsWith("org.jboss.weld")) {
+            return null;
+        }
+        Bean<?> interceptedBean = null;
+        try {
+            // Note that we need to support both 2.x and 3.x
+            Class<?> ctxImplClazz;
+            if (ctx.getClass().getName().startsWith("org.jboss.weld.contexts")) {
+                // 3.x
+                ctxImplClazz = MockInterceptor.class.getClassLoader().loadClass("org.jboss.weld.contexts.CreationalContextImpl");
+            } else {
+                // 2.x
+                ctxImplClazz = MockInterceptor.class.getClassLoader().loadClass("org.jboss.weld.context.CreationalContextImpl");
+            }
+            Object parentContext = ctxImplClazz.getMethod("getParentCreationalContext").invoke(ctx);
+            if (parentContext != null) {
+                Contextual<?> interceptedContextual = (Contextual<?>) ctxImplClazz.getMethod("getContextual").invoke(parentContext);
+                if (interceptedContextual instanceof Bean<?>) {
+                    interceptedBean = (Bean<?>) interceptedContextual;
+                }
+            }
+        } catch (Exception e) {
+            throw new IllegalStateException(e);
+        }
+        return interceptedBean;
+    }
+
+    public static class MockInterceptorInstance implements Serializable {
+
+        private static final long serialVersionUID = -1623826535751475203L;
+
+        private final SerializableForwardingBean<?> interceptedBean;
+
+        MockInterceptorInstance(Bean<?> interceptedBean, String contextId) {
+            this.interceptedBean = interceptedBean != null ? SerializableForwardingBean.of(contextId, interceptedBean) : null;
+        }
+
+        public Bean<?> getInterceptedBean() {
+            return interceptedBean;
+        }
+
+    }
+
+    public static class Builder {
+
+        private Set<Annotation> bindings = new HashSet<>();
+
+        private InterceptionType type;
+
+        private InterceptionCallback callback;
+
+        private Class<?> beanClass;
+
+        /**
+         *
+         * @param bindings
+         * @return self
+         */
+        Builder bindings(Annotation... bindings) {
+            this.bindings.clear();
+            Collections.addAll(this.bindings, bindings);
+            return this;
+        }
+
+        /**
+         *
+         * @param type
+         * @return self
+         */
+        public Builder type(InterceptionType type) {
+            this.type = type;
+            return this;
+        }
+
+        /**
+         * Allows to specify a bean class of an interceptor. This is only required if you later on need to enforce interceptor ordering via
+         * <code>Weld.enableInterceptors()</code>. Note that such ordering corresponds to enabling interceptors via beans.xml (e.g. per bean archive).
+         *
+         * @param beanClass
+         * @return self
+         */
+        public Builder beanClass(Class<?> beanClass) {
+            this.beanClass = beanClass;
+            return this;
+        }
+
+        /**
+         *
+         * @param function The interception callback, intercepted bean might be <code>null</code>
+         * @return self
+         */
+        public Builder callback(InterceptionCallback callback) {
+            this.callback = callback;
+            return this;
+        }
+
+        public MockInterceptor aroundInvoke(InterceptionCallback callback) {
+            return type(InterceptionType.AROUND_INVOKE).callback(callback).build();
+        }
+
+        public MockInterceptor aroundConstruct(InterceptionCallback callback) {
+            return type(InterceptionType.AROUND_CONSTRUCT).callback(callback).build();
+        }
+
+        public MockInterceptor postConstruct(InterceptionCallback callback) {
+            return type(InterceptionType.POST_CONSTRUCT).callback(callback).build();
+        }
+
+        public MockInterceptor preDestroy(InterceptionCallback callback) {
+            return type(InterceptionType.PRE_DESTROY).callback(callback).build();
+        }
+
+        public MockInterceptor build() {
+            if (type == null) {
+                throw new IllegalStateException("Interception type not set");
+            }
+            if (callback == null) {
+                throw new IllegalStateException("Interception callback not set");
+            }
+            if (bindings.isEmpty()) {
+                throw new IllegalStateException("No interceptor bindings specified");
+            }
+            return new MockInterceptor(beanClass != null ? beanClass : MockInterceptor.class, type, callback, bindings);
+        }
+
+    }
+
+    @FunctionalInterface
+    public interface InterceptionCallback {
+
+        /**
+         *
+         * @param invocationContext
+         * @param interceptedBean May be <code>null</code>
+         * @return the result
+         */
+        Object invoke(InvocationContext invocationContext, Bean<?> interceptedBean) throws Exception;
+
+    }
+
+}
diff --git a/junit4/README.md b/junit4/README.md
index 2040664..fdb7b85 100644
--- a/junit4/README.md
+++ b/junit4/README.md
@@ -175,7 +175,7 @@ class TestClassProducerTest {
 
 This should work in most of the cases (assuming the test class [meets some conditions](http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#what_classes_are_beans)) although it's a little bit cumbersome.
 The second option is `WeldInitiator.Builder.addBeans(Bean<?>...)` which makes it possible to add beans during `AfterBeanDiscovery` phase easily.
-You can provide your own `javax.enterprise.inject.spi.Bean` implementation or make use of existing solutions such as DeltaSpike [BeanBuilder](https://github.com/apache/deltaspike/blob/master/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/bean/BeanBuilder.java) or for most use cases a convenient `org.jboss.weld.junit4.MockBean` should be sufficient.
+You can provide your own `javax.enterprise.inject.spi.Bean` implementation or make use of existing solutions such as DeltaSpike [BeanBuilder](https://github.com/apache/deltaspike/blob/master/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/bean/BeanBuilder.java) or for most use cases a convenient `org.jboss.weld.junit.MockBean` should be sufficient.
 Use `org.jboss.weld.junit.MockBean.builder()` to obtain a new builder instance.
 
 ```java
@@ -213,3 +213,44 @@ class AddBeanTest {
     }
 }
 ```
+
+#### Adding mock interceptors
+
+Sometimes it might be useful to add a mock interceptor, e.g. if an interceptor implementation requires some environment-specific features.
+For this use case the `org.jboss.weld.junit.MockInterceptor` is a perfect match:
+
+```
+@FooBinding
+class Foo {
+   boolean ping() {
+      return true;
+   }
+}
+
+@Target({ TYPE, METHOD })
+@Retention(RUNTIME)
+@InterceptorBinding
+@interface FooBinding {
+
+   @SuppressWarnings("serial")
+   static final class Literal extends AnnotationLiteral<FooBinding> implements FooBinding {
+      public static final Literal INSTANCE = new Literal();
+    };
+   }
+}
+
+class MockInterceptorTest {
+
+    @Rule
+    public WeldInitiator weld = WeldInitiator.from(Foo.class).addBeans(
+            MockInterceptor.withBindings(FooBinding.Literal.INSTANCE).aroundInvoke((ctx, b) -> {
+                return false;
+                })).build();
+
+
+    @Test
+    public void testInterception() {
+       Assert.assertFalse(weld.select(Foo.class).get().ping());
+    }
+}
+```
diff --git a/junit5/README.md b/junit5/README.md
index 7d6b31e..dd5a26c 100644
--- a/junit5/README.md
+++ b/junit5/README.md
@@ -243,7 +243,7 @@ class TestClassProducerTest {
 
 This should work in most of the cases (assuming the test class [meets some conditions](http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#what_classes_are_beans)) although it's a little bit cumbersome.
 The second option is `WeldInitiator.Builder.addBeans(Bean<?>...)` which makes it possible to add beans during `AfterBeanDiscovery` phase easily.
-You can provide your own `javax.enterprise.inject.spi.Bean` implementation or make use of existing solutions such as DeltaSpike [BeanBuilder](https://github.com/apache/deltaspike/blob/master/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/bean/BeanBuilder.java) or for most use cases a convenient `org.jboss.weld.junit4.MockBean` should be sufficient.
+You can provide your own `javax.enterprise.inject.spi.Bean` implementation or make use of existing solutions such as DeltaSpike [BeanBuilder](https://github.com/apache/deltaspike/blob/master/deltaspike/core/api/src/main/java/org/apache/deltaspike/core/util/bean/BeanBuilder.java) or for most use cases a convenient `org.jboss.weld.junit.MockBean` should be sufficient.
 Use `org.jboss.weld.junit.MockBean.builder()` to obtain a new builder instance.
 
 ```java
@@ -283,6 +283,47 @@ class AddBeanTest {
 }
 ```
 
+#### Adding mock interceptors
+
+Sometimes it might be useful to add a mock interceptor, e.g. if an interceptor implementation requires some environment-specific features.
+For this use case the `org.jboss.weld.junit.MockInterceptor` is a perfect match:
+
+```
+@FooBinding
+class Foo {
+   boolean ping() {
+      return true;
+   }
+}
+
+@Target({ TYPE, METHOD })
+@Retention(RUNTIME)
+@InterceptorBinding
+@interface FooBinding {
+
+   @SuppressWarnings("serial")
+   static final class Literal extends AnnotationLiteral<FooBinding> implements FooBinding {
+      public static final Literal INSTANCE = new Literal();
+    };
+   }
+}
+
+class MockInterceptorTest {
+
+    @Rule
+    public WeldInitiator weld = WeldInitiator.from(Foo.class).addBeans(
+            MockInterceptor.withBindings(FooBinding.Literal.INSTANCE).aroundInvoke((ctx, b) -> {
+                return false;
+                })).build();
+
+
+    @Test
+    public void testInterception() {
+       Assert.assertFalse(weld.select(Foo.class).get().ping());
+    }
+}
+```
+
 ## Additional Configuration
 
 This section describes any additional configuration options this extension offers.


Test patch:
diff --git a/junit4/src/test/java/org/jboss/weld/junit4/interceptor/MockInterceptorOrderingTest.java b/junit4/src/test/java/org/jboss/weld/junit4/interceptor/MockInterceptorOrderingTest.java
new file mode 100644
index 0000000..754c881
--- /dev/null
+++ b/junit4/src/test/java/org/jboss/weld/junit4/interceptor/MockInterceptorOrderingTest.java
@@ -0,0 +1,91 @@
+/*
+ * 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.junit4.interceptor;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import javax.enterprise.util.AnnotationLiteral;
+import javax.interceptor.InterceptorBinding;
+
+import org.jboss.weld.junit.MockInterceptor;
+import org.jboss.weld.junit4.WeldInitiator;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class MockInterceptorOrderingTest {
+
+    private static AtomicBoolean guard = new AtomicBoolean();
+
+    @Rule
+    public WeldInitiator weld = WeldInitiator.from(WeldInitiator.createWeld().addBeanClass(Foo.class).enableInterceptors(Integer.class, String.class)).addBeans(
+            MockInterceptor.withBindings(FooBinding.Literal.INSTANCE).beanClass(Integer.class).aroundInvoke((ctx, b) -> {
+                return 5;
+                }),
+            MockInterceptor.withBindings(FooBinding.Literal.INSTANCE).beanClass(String.class).aroundInvoke((ctx, b) -> {
+                // Should be never invoked
+                guard.set(true);
+                return -5;
+                })).build();
+
+    @Before
+    public void setup() {
+        guard.set(false);
+    }
+
+    @Test
+    public void testOrdering() {
+        assertFalse(guard.get());
+        assertEquals(5, weld.select(Foo.class).get().ping());
+    }
+
+    @FooBinding
+    static class Foo {
+
+        int ping() {
+            // Should be never invoked
+            guard.set(true);
+            return 1;
+        }
+
+    }
+
+    @Target({ TYPE, METHOD })
+    @Retention(RUNTIME)
+    @Documented
+    @InterceptorBinding
+    static @interface FooBinding {
+
+        @SuppressWarnings("serial")
+        static final class Literal extends AnnotationLiteral<FooBinding> implements FooBinding {
+
+            public static final Literal INSTANCE = new Literal();
+
+        };
+
+    }
+
+}
diff --git a/junit4/src/test/java/org/jboss/weld/junit4/interceptor/MockInterceptorTest.java b/junit4/src/test/java/org/jboss/weld/junit4/interceptor/MockInterceptorTest.java
new file mode 100644
index 0000000..5d401fa
--- /dev/null
+++ b/junit4/src/test/java/org/jboss/weld/junit4/interceptor/MockInterceptorTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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.junit4.interceptor;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.enterprise.inject.spi.InterceptionType;
+import javax.enterprise.inject.spi.Interceptor;
+import javax.enterprise.util.AnnotationLiteral;
+import javax.interceptor.InterceptorBinding;
+
+import org.jboss.weld.junit.MockInterceptor;
+import org.jboss.weld.junit4.WeldInitiator;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+
+public class MockInterceptorTest {
+
+    private List<String> aroundInvokes;
+
+    private List<String> postConstructs;
+
+    @Rule
+    public WeldInitiator weld = WeldInitiator.from(Foo.class).addBeans(
+            MockInterceptor.withBindings(FooBinding.Literal.INSTANCE).aroundInvoke((ctx, b) -> {
+                aroundInvokes.add(b.getBeanClass().getName());
+                return ctx.proceed();
+                }),
+            // This interceptor is disabled
+            MockInterceptor.withBindings(FooBinding.Literal.INSTANCE).beanClass(String.class).aroundInvoke((ctx, b) -> {
+                return false;
+                }),
+            MockInterceptor.withBindings(FooBinding.Literal.INSTANCE).postConstruct((ctx, b) -> postConstructs.add(b.getBeanClass().getName()))).build();
+
+    @Before
+    public void setup() {
+        aroundInvokes = new ArrayList<>();
+        postConstructs = new ArrayList<>();
+    }
+
+    @Test
+    public void testInterception() {
+        assertTrue(aroundInvokes.isEmpty());
+        assertTrue(postConstructs.isEmpty());
+        assertTrue(weld.select(Foo.class).get().ping());
+        assertEquals(1, aroundInvokes.size());
+        assertEquals(Foo.class.getName(), aroundInvokes.get(0));
+        assertEquals(1, postConstructs.size());
+        assertEquals(Foo.class.getName(), postConstructs.get(0));
+    }
+
+    @Test
+    public void testDisabledInterceptor() {
+        List<Interceptor<?>> interceptors = weld.getBeanManager().resolveInterceptors(InterceptionType.AROUND_INVOKE, FooBinding.Literal.INSTANCE);
+        assertEquals(1, interceptors.size());
+        assertEquals(MockInterceptor.class, interceptors.get(0).getBeanClass());
+    }
+
+    @FooBinding
+    static class Foo {
+
+        boolean ping() {
+            return true;
+        }
+
+    }
+
+    @Target({ TYPE, METHOD })
+    @Retention(RUNTIME)
+    @Documented
+    @InterceptorBinding
+    static @interface FooBinding {
+
+        @SuppressWarnings("serial")
+        static final class Literal extends AnnotationLiteral<FooBinding> implements FooBinding {
+
+            public static final Literal INSTANCE = new Literal();
+
+        };
+
+    }
+
+}
diff --git a/junit5/src/test/java/org/jboss/weld/junit5/interceptor/MockInterceptorTest.java b/junit5/src/test/java/org/jboss/weld/junit5/interceptor/MockInterceptorTest.java
new file mode 100644
index 0000000..e8eb772
--- /dev/null
+++ b/junit5/src/test/java/org/jboss/weld/junit5/interceptor/MockInterceptorTest.java
@@ -0,0 +1,110 @@
+/*
+ * 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.junit5.interceptor;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.enterprise.inject.spi.InterceptionType;
+import javax.enterprise.inject.spi.Interceptor;
+import javax.enterprise.util.AnnotationLiteral;
+import javax.interceptor.InterceptorBinding;
+
+import org.jboss.weld.junit.MockInterceptor;
+import org.jboss.weld.junit5.EnableWeld;
+import org.jboss.weld.junit5.WeldInitiator;
+import org.jboss.weld.junit5.WeldSetup;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+@EnableWeld
+public class MockInterceptorTest {
+
+    private List<String> aroundInvokes;
+
+    private List<String> postConstructs;
+
+    @WeldSetup
+    public WeldInitiator weld = WeldInitiator.from(Foo.class).addBeans(
+            MockInterceptor.withBindings(FooBinding.Literal.INSTANCE).aroundInvoke((ctx, b) -> {
+                aroundInvokes.add(b.getBeanClass().getName());
+                return ctx.proceed();
+                }),
+            // This interceptor is disabled
+            MockInterceptor.withBindings(FooBinding.Literal.INSTANCE).beanClass(String.class).aroundInvoke((ctx, b) -> {
+                return false;
+                }),
+            MockInterceptor.withBindings(FooBinding.Literal.INSTANCE).postConstruct((ctx, b) -> postConstructs.add(b.getBeanClass().getName()))).build();
+
+    @BeforeEach
+    public void setup() {
+        aroundInvokes = new ArrayList<>();
+        postConstructs = new ArrayList<>();
+    }
+
+    @Test
+    public void testInterception() {
+        assertTrue(aroundInvokes.isEmpty());
+        assertTrue(postConstructs.isEmpty());
+        assertTrue(weld.select(Foo.class).get().ping());
+        assertEquals(1, aroundInvokes.size());
+        assertEquals(Foo.class.getName(), aroundInvokes.get(0));
+        assertEquals(1, postConstructs.size());
+        assertEquals(Foo.class.getName(), postConstructs.get(0));
+    }
+
+    @Test
+    public void testDisabledInterceptor() {
+        List<Interceptor<?>> interceptors = weld.getBeanManager().resolveInterceptors(InterceptionType.AROUND_INVOKE, FooBinding.Literal.INSTANCE);
+        assertEquals(1, interceptors.size());
+        assertEquals(MockInterceptor.class, interceptors.get(0).getBeanClass());
+    }
+
+    @FooBinding
+    static class Foo {
+
+        boolean ping() {
+            return true;
+        }
+
+    }
+
+    @Target({ TYPE, METHOD })
+    @Retention(RUNTIME)
+    @Documented
+    @InterceptorBinding
+    static @interface FooBinding {
+
+        @SuppressWarnings("serial")
+        static final class Literal extends AnnotationLiteral<FooBinding> implements FooBinding {
+
+            public static final Literal INSTANCE = new Literal();
+
+        };
+
+    }
+
+}