/* * JBoss, Home of Professional Open Source * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors * as indicated by the @authors tag. All rights reserved. * 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.arquillian.test.impl.enricher.resource; import java.lang.annotation.Annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.Target; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Arrays; import java.util.List; import org.jboss.arquillian.core.api.Injector; import org.jboss.arquillian.core.api.Instance; import org.jboss.arquillian.core.api.annotation.ApplicationScoped; import org.jboss.arquillian.core.api.annotation.Inject; import org.jboss.arquillian.core.spi.ServiceLoader; import org.jboss.arquillian.test.api.ArquillianResource; import org.jboss.arquillian.test.spi.TestEnricher; import org.jboss.arquillian.test.spi.enricher.resource.ResourceProvider; import org.jboss.arquillian.test.test.AbstractTestTestBase; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentMatcher; import org.mockito.Mock; import org.mockito.Mockito; import org.mockito.internal.matchers.VarargMatcher; import org.mockito.runners.MockitoJUnitRunner; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * ArquillianTestEnricherTestCase * * @author <a href="mailto:aslak@redhat.com">Aslak Knutsen</a> * @author Vineet Reynolds * @version $Revision: $ */ @RunWith(MockitoJUnitRunner.class) public class ArquillianResourceTestEnricherTestCase extends AbstractTestTestBase { @Inject private Instance<Injector> injector; @Mock private ServiceLoader serviceLoader; @Mock private ResourceProvider resourceProvider; @Mock private Object resource; @Before public void addServiceLoader() throws Exception { List<ResourceProvider> resourceProviders = Arrays.asList(resourceProvider); Mockito.when(serviceLoader.all(ResourceProvider.class)).thenReturn(resourceProviders); Mockito.when(resourceProvider.canProvide(Object.class)).thenReturn(true); bind(ApplicationScoped.class, ServiceLoader.class, serviceLoader); } @Test public void shouldBeAbleToInjectBaseContext() throws Exception { Mockito.when(resourceProvider.lookup( (ArquillianResource) Mockito.any(), Mockito.argThat(new ClassInjectionAnnotationMatcher()))) .thenReturn(resource); TestEnricher enricher = new ArquillianResourceTestEnricher(); injector.get().inject(enricher); ObjectClass test = new ObjectClass(); enricher.enrich(test); Assert.assertEquals(resource, test.resource); } @Test public void shouldBeAbleToInjectBaseContextOnMethod() throws Exception { Method resourceMethod = ObjectClass.class.getMethod("test", Object.class); Mockito.when( resourceProvider.lookup( (ArquillianResource) Mockito.any(), Mockito.argThat(new MethodInjectionAnnotationMatcher()))) .thenReturn(resource); TestEnricher enricher = new ArquillianResourceTestEnricher(); injector.get().inject(enricher); Object[] result = enricher.resolve(resourceMethod); Assert.assertEquals(resource, result[0]); } @Test public void shouldBeAbleToInjectBaseContextWithQualifier() throws Exception { Field resource2Field = ObjectClass2.class.getField("resource2"); Mockito.when( resourceProvider.lookup( (ArquillianResource) Mockito.any(), Mockito.argThat( new CustomAnnotationMatcher( resource2Field.getAnnotation(ArquillianTestQualifier.class), ResourceProvider.ClassInjection.class)))) .thenReturn(resource); TestEnricher enricher = new ArquillianResourceTestEnricher(); injector.get().inject(enricher); ObjectClass2 test = new ObjectClass2(); enricher.enrich(test); Assert.assertEquals(resource, test.resource2); } @Test public void shouldBeAbleToInjectBaseContextOnMethodWithQualifier() throws Exception { Method resourceMethod = ObjectClass.class.getMethod("testWithQualifier", Object.class); Mockito.when( resourceProvider.lookup( (ArquillianResource) Mockito.any(), Mockito.argThat( new CustomAnnotationMatcher( resourceMethod.getParameterAnnotations()[0][1], ResourceProvider.MethodInjection.class)))) .thenReturn(resource); TestEnricher enricher = new ArquillianResourceTestEnricher(); injector.get().inject(enricher); Object[] result = enricher.resolve(resourceMethod); Assert.assertEquals(resource, result[0]); } @Test public void shouldThrowExceptionWhenUsedMethodScopeInjectionOnArquillianResource() throws Exception { Method resourceMethod = ObjectClass3.class.getMethod("testWithInjectionQualifier", Object.class); Mockito.when( resourceProvider.lookup( (ArquillianResource) Mockito.any(), Mockito.argThat( new CustomAnnotationMatcher( resourceMethod.getParameterAnnotations()[0][1], ResourceProvider.MethodInjection.class)))) .thenReturn(resource); TestEnricher enricher = new ArquillianResourceTestEnricher(); injector.get().inject(enricher); Throwable cause = null; try { enricher.resolve(resourceMethod); } catch (Exception ex) { cause = ex; } Assert.assertEquals(IllegalStateException.class, cause.getClass()); } @Test public void shouldThrowExceptionWhenUsedClassScopeInjectionOnArquillianResource() { Mockito.when( resourceProvider.lookup( (ArquillianResource) Mockito.any(), Mockito.argThat( new ClassInjectionAnnotationMatcher()))) .thenReturn(resource); TestEnricher enricher = new ArquillianResourceTestEnricher(); injector.get().inject(enricher); ObjectClass3 test = new ObjectClass3(); Throwable cause = null; try { enricher.enrich(test); } catch (RuntimeException ex) { cause = ex.getCause(); } Assert.assertEquals(IllegalStateException.class, cause.getClass()); } @Retention(RUNTIME) @Target({ElementType.FIELD, ElementType.PARAMETER}) public @interface ArquillianTestQualifier { } public class ObjectClass { @ArquillianResource public Object resource; public void test(@ArquillianResource Object resource) { } public void testWithQualifier(@ArquillianResource @ArquillianTestQualifier Object resource) { } } public class ObjectClass2 { @ArquillianResource @ArquillianTestQualifier public Object resource2; } public class ObjectClass3 { @ArquillianResource @ResourceProvider.ClassInjection public Object resource; public void testWithInjectionQualifier(@ArquillianResource @ResourceProvider.MethodInjection Object resource) { } } private class ClassInjectionAnnotationMatcher extends ArgumentMatcher<Annotation[]> implements VarargMatcher { private static final long serialVersionUID = 7468313136186740343L; @Override public boolean matches(Object varargArgument) { Class<?> qualifier = ((Annotation) varargArgument).annotationType(); return qualifier.equals(ResourceProvider.ClassInjection.class); } } private class MethodInjectionAnnotationMatcher extends ArgumentMatcher<Annotation[]> implements VarargMatcher { private static final long serialVersionUID = 7468313136186740343L; @Override public boolean matches(Object varargArgument) { Class<?> qualifier = ((Annotation) varargArgument).annotationType(); return qualifier.equals(ResourceProvider.MethodInjection.class); } } private class CustomAnnotationMatcher extends ArgumentMatcher<Annotation[]> implements VarargMatcher { private static final long serialVersionUID = 7468313136186740343L; private Annotation additionalQualifier; private Class<? extends Annotation> injectionScope; public CustomAnnotationMatcher(Annotation additionalQualifier, Class<? extends Annotation> injectionScope) { this.additionalQualifier = additionalQualifier; this.injectionScope = injectionScope; } @Override public boolean matches(Object varargArgument) { Annotation[] annotations = (Annotation[]) varargArgument; return annotations.length == 2 && annotations[0].annotationType().equals(additionalQualifier.annotationType()) && annotations[1].annotationType().equals(injectionScope); } } }