SLING-3751 - Create a JUnit rule to inject a service reference into a test
* applied patch from Francesco Mari (thx!)
git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1609055 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/pom.xml b/pom.xml
index 60c0222..f06bbeb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -35,7 +35,8 @@
<description>Runs JUnit tests in an OSGi framework and provides the JUnit libraries</description>
<properties>
- <junit.version>4.8.2</junit.version>
+ <junit.version>4.11</junit.version>
+ <hamcrest.version>1.3</hamcrest.version>
<jacoco.version>0.6.2.201302030002</jacoco.version>
</properties>
@@ -60,6 +61,7 @@
<Bundle-Activator>org.apache.sling.junit.Activator</Bundle-Activator>
<Export-Package>
org.apache.sling.junit;version=1.2.0,
+ org.apache.sling.junit.rules;version=1.0.10,
org.apache.sling.junit.annotations;version=1.0.8,
</Export-Package>
<_exportcontents>
@@ -68,10 +70,16 @@
org.junit.matchers.*;version=${junit.version},
org.junit.rules.*;version=${junit.version},
org.junit.runner.*;version=${junit.version},
- org.junit.runners.*;version=${junit.version}
+ org.junit.runners.*;version=${junit.version},
+ org.hamcrest.*;version=${hamcrest.version},
+ org.hamcrest.core.*;version=${hamcrest.version}
</_exportcontents>
<Private-Package>org.apache.sling.junit.impl.*</Private-Package>
- <Embed-Dependency>org.jacoco.agent;classifier=runtime;inline=org/jacoco/agent/rt/IAgent.class,*;artifactId=junit</Embed-Dependency>
+ <Embed-Dependency>
+ org.jacoco.agent;classifier=runtime;inline=org/jacoco/agent/rt/IAgent.class,
+ *;artifactId=junit,
+ *;artifactId=hamcrest-core
+ </Embed-Dependency>
</instructions>
</configuration>
</plugin>
@@ -152,6 +160,11 @@
<version>${jacoco.version}</version>
<scope>provided</scope>
</dependency>
-
+ <dependency>
+ <groupId>org.hamcrest</groupId>
+ <artifactId>hamcrest-core</artifactId>
+ <version>${hamcrest.version}</version>
+ <scope>provided</scope>
+ </dependency>
</dependencies>
</project>
diff --git a/src/main/java/org/apache/sling/junit/rules/Service.java b/src/main/java/org/apache/sling/junit/rules/Service.java
new file mode 100644
index 0000000..d580149
--- /dev/null
+++ b/src/main/java/org/apache/sling/junit/rules/Service.java
@@ -0,0 +1,88 @@
+/*
+ * 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.sling.junit.rules;
+
+import org.apache.sling.junit.Activator;
+import org.junit.rules.TestRule;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+/**
+ * Allows a test class to obtain a reference to an OSGi service. This rule embodies the logic to get a bundle context,
+ * obtain a service reference, fetch the reference to the object and perform the proper cleanup after the test has run.
+ */
+public class Service implements TestRule {
+
+ private final Class<?> serviceClass;
+
+ private Object service;
+
+ public Service(Class<?> serviceClass) {
+ this.serviceClass = serviceClass;
+ }
+
+ public Statement apply(final Statement base, final Description description) {
+ return new Statement() {
+
+ @Override
+ public void evaluate() throws Throwable {
+ final BundleContext bundleContext = Activator.getBundleContext();
+
+ if (bundleContext == null) {
+ throw new IllegalStateException("unable to obtain a bundle context");
+ }
+
+ final ServiceReference serviceReference = bundleContext.getServiceReference(serviceClass.getName());
+
+ if (serviceReference == null) {
+ throw new IllegalStateException("unable to get a service reference");
+ }
+
+ final Object service = bundleContext.getService(serviceReference);
+
+ if (service == null) {
+ throw new IllegalStateException("unable to get an instance of the service");
+ }
+
+ Service.this.service = serviceClass.cast(service);
+
+ try {
+ base.evaluate();
+ } finally {
+ Service.this.service = null;
+ bundleContext.ungetService(serviceReference);
+ }
+ }
+
+ };
+ }
+
+ /**
+ * Return the service object.
+ *
+ * @param serviceClass Use this class to perform a cast before the object is returned.
+ * @param <T> The type of the service.
+ * @return The service object.
+ */
+ public <T> T getService(Class<T> serviceClass) {
+ return serviceClass.cast(service);
+ }
+
+}