/* * Copyright (C) 2011 Harald Wellmann * * 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.ops4j.pax.exam.regression.multi.wrap; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import static org.ops4j.pax.exam.CoreOptions.frameworkProperty; import static org.ops4j.pax.exam.CoreOptions.junitBundles; import static org.ops4j.pax.exam.CoreOptions.mavenBundle; import static org.ops4j.pax.exam.CoreOptions.options; import static org.ops4j.pax.exam.CoreOptions.repository; import static org.ops4j.pax.exam.CoreOptions.systemProperty; import static org.ops4j.pax.exam.CoreOptions.wrappedBundle; import static org.ops4j.pax.exam.regression.multi.RegressionConfiguration.regressionDefaults; import java.util.List; import org.junit.Test; import org.junit.runner.RunWith; import org.ops4j.pax.exam.Configuration; import org.ops4j.pax.exam.Info; import org.ops4j.pax.exam.Option; import org.ops4j.pax.exam.junit.PaxExam; import org.ops4j.pax.exam.sample9.pde.HelloService; import org.ops4j.pax.exam.spi.reactors.ExamReactorStrategy; import org.ops4j.pax.exam.spi.reactors.PerMethod; /** * This test shows * <ul> * <li>how to use the {@code wrappedBundle()} option</li> * <li>how to set the version of exported packages with {@code wrappedBundle()}.</li> * <li>how to use both Mockito and JUnit and avoid a conflict with the Hamcrest library which is * embedded in each of the two by default.</li> * <li>how to suppress classloader issues caused by CGLIB proxies in Mockito and implicit boot * delegation in Felix</li> * * </ul> * See PAXEXAM-274. * * @author Harald Wellmann * */ @RunWith(PaxExam.class) @ExamReactorStrategy(PerMethod.class) public class MockitoTest { @Configuration public Option[] config1() { return options( regressionDefaults(), // A simple test bundle mavenBundle("org.ops4j.pax.exam.samples", "pax-exam-sample9-pde", Info.getPaxExamVersion()), // Mockito with Hamcrest and Objenesis embedded mavenBundle("org.mockito", "mockito-all", "1.9.5"), // JUnit without Hamcrest wrappedBundle(mavenBundle("junit", "junit-dep", "4.10")).exports("*;version=4.10"), systemProperty("pax.exam.invoker").value("junit"), mavenBundle("org.ops4j.pax.exam", "pax-exam-invoker-junit", Info.getPaxExamVersion()), /* * Felix has implicit boot delegation enabled by default, which causes the following * exception: * * loader constraint violation in interface itable initialization: when resolving method * "org.ops4j.pax.exam.sample9.pde.HelloService$$EnhancerByMockitoWithCGLIB$$451e2809.newInstance(Lorg/mockito/cglib/proxy/Callback;)Ljava/lang/Object;" * the class loader (instance of * org/mockito/internal/creation/jmock/SearchingClassLoader) of the current class, * org/ops4j/pax/exam/regression/pde/HelloService$$EnhancerByMockitoWithCGLIB$$451e2809, * and the class loader (instance of * org/apache/felix/framework/ModuleImpl$ModuleClassLoaderJava5) for interface * org/mockito/cglib/proxy/Factory have different Class objects for the type * org/mockito/cglib/proxy/Callback used in the signature * * The bundle classloader of pax-exam-sample9-pde loads org.mockito.cglib.proxy.Factory * via boot delegation from the app class loader, which conflicts with the class loaded * by the Mockito bundle class loader. * * See ModuleImpl.doImplicitBootDelegation() in Felix. */ frameworkProperty("felix.bootdelegation.implicit").value("false") ); } @Configuration public Option[] config2() { return options( regressionDefaults(), repository("http://repository.springsource.com/maven/bundles/external").id( "com.springsource.repository.bundles.external"), // A simple test bundle mavenBundle("org.ops4j.pax.exam.samples", "pax-exam-sample9-pde", Info.getPaxExamVersion()), // Mockito without Hamcrest and Objenesis mavenBundle("org.mockito", "mockito-core", "1.9.5"), // Hamcrest with a version matching the range expected by Mockito mavenBundle("org.hamcrest", "com.springsource.org.hamcrest.core", "1.1.0"), // Objenesis with a version matching the range expected by Mockito wrappedBundle(mavenBundle("org.objenesis", "objenesis", "1.2")) .exports("*;version=1.2"), // The default JUnit bundle also exports Hamcrest, but with an (incorrect) version of // 4.9 which does not match the Mockito import. junitBundles(), // see config1() frameworkProperty("felix.bootdelegation.implicit").value("false")); } /** * This test does not produce the boot delegation issue, since the mocked interface is loaded * via the system class loader. */ @Test @SuppressWarnings("unchecked") public void createMock() { List<String> list = mock(List.class); when(list.size()).thenReturn(0); int size = list.size(); assertEquals(0, size); } /** * Here we mock an interface from our test bundle. Set felix.bootdelegation.implicit = true to * fail this test. */ @Test public void bootDelegation() { HelloService service = mock(HelloService.class); service.getMessage(); } }