Permalink
Browse files

Instrument detection: formatting and tests

  • Loading branch information...
1 parent e338783 commit b6a3c55b23e19634c4968b9198e680a34f287acb @roman-mazur roman-mazur committed Mar 30, 2012
Showing with 175 additions and 0 deletions.
  1. +175 −0 src/test/java/com/xtremelabs/robolectric/InstrumentDetectorTest.java
View
175 src/test/java/com/xtremelabs/robolectric/InstrumentDetectorTest.java
@@ -0,0 +1,175 @@
+package com.xtremelabs.robolectric;
+
+import static com.xtremelabs.robolectric.util.TestUtil.resourceFile;
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+import org.junit.Test;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+import org.junit.runners.model.InitializationError;
+
+import com.xtremelabs.robolectric.RobolectricTestRunner.InstrumentDetector;
+import com.xtremelabs.robolectric.bytecode.ClassHandler;
+import com.xtremelabs.robolectric.bytecode.RobolectricClassLoader;
+import com.xtremelabs.robolectric.bytecode.ShadowWrangler;
+
+/**
+ * Tests related to custom instrument detection strategy
+ * that is used for introducing custom class loaders to test runners.
+ */
+public class InstrumentDetectorTest {
+
+ // ==================== CLASSLOADER ====================
+
+ /** Custom class loader. It must be singleton. */
+ public static class ClassLoaderForTesting extends RobolectricClassLoader {
+
+ /** Instance. */
+ private static ClassLoaderForTesting instance;
+
+ /** Usage flag. */
+ static boolean usageFlag = false;
+
+ public static ClassLoaderForTesting getInstance() {
+ if (instance == null) {
+ instance = new ClassLoaderForTesting(ShadowWrangler.getInstance());
+ }
+ return instance;
+ }
+
+ protected ClassLoaderForTesting(final ClassHandler classHandler) {
+ super(classHandler);
+ }
+
+ @Override
+ public Class<?> loadClass(final String name) throws ClassNotFoundException {
+ if (!usageFlag) {
+ System.setProperty("robolectric.cusomClassLoader", "yes");
+ }
+ usageFlag = true;
+ return super.loadClass(name);
+ }
+
+ }
+
+ // ==================== RUNNERS ====================
+
+ /** Custom runner that uses custom class loader but does not modify instrument detection. */
+ public static class RunnerForTesting extends RobolectricTestRunner {
+
+ public RunnerForTesting(final Class<?> testClass) throws InitializationError {
+ super(
+ testClass,
+ isInstrumented() ? null : ShadowWrangler.getInstance(),
+ isInstrumented() ? null : ClassLoaderForTesting.getInstance(),
+ new RobolectricConfig(resourceFile("TestAndroidManifest.xml"), resourceFile("res"), resourceFile("assets"))
+ );
+ }
+
+ }
+
+ /** Custom runner that uses custom class loader. */
+ public static class RunnerForTestingThatWillPass extends RobolectricTestRunner {
+
+ static {
+ RunnerForTestingThatWillPass.setInstrumentDetector(CUSTOM_DETECTOR);
+ }
+
+ public RunnerForTestingThatWillPass(final Class<?> testClass) throws InitializationError {
+ super(
+ testClass,
+ isInstrumented() ? null : ShadowWrangler.getInstance(),
+ isInstrumented() ? null : ClassLoaderForTesting.getInstance(),
+ new RobolectricConfig(resourceFile("TestAndroidManifest.xml"), resourceFile("res"), resourceFile("assets"))
+ );
+ }
+
+ }
+
+ /** Custom instrument detector. */
+ private static final InstrumentDetector CUSTOM_DETECTOR = new InstrumentDetector() {
+ @Override
+ public boolean isInstrumented() {
+ final String currentLoader = RunnerForTestingThatWillPass.class.getClassLoader().getClass().getName();
+ return currentLoader.contains(ClassLoaderForTesting.class.getName());
+ }
+ };
+
+
+ // ==================== TEST CLASSES ====================
+
+ /**
+ * Default behavior test.
+ */
+ public static class DefaultBehaviorTest {
+ @Test
+ public void fakeTest() {
+ assertThat(true, equalTo(true));
+ }
+ }
+
+ /**
+ * Test that is launched with a custom test runner and will fail.
+ */
+ @RunWith(RunnerForTesting.class)
+ public static class TestWithCustomRunner {
+ @Test
+ public void loadedWithCustomClassLoader_usageFlagShoudBeTrue() {
+ assertThat(System.getProperty("robolectric.cusomClassLoader"), equalTo("yes"));
+ }
+ }
+
+ /**
+ * Test that is launched with a custom test runner and will pass.
+ */
+ @RunWith(RunnerForTestingThatWillPass.class)
+ public static class TestWithCustomRunnerThatWillPass extends TestWithCustomRunner {
+ // nothing here, we just need another annotation
+ }
+
+
+ // ==================== RUN METHODS ====================
+
+ /**
+ * This is default behavior.
+ */
+ @Test
+ public void withDefaultDetectorAndDefaultRunner_shouldPass() {
+ final Result result = JUnitCore.runClasses(DefaultBehaviorTest.class);
+ assertThat(result.getRunCount(), equalTo(1));
+ assertThat(result.getFailureCount(), equalTo(0));
+ }
+
+ /**
+ * This test simulates wrong instrument detection when custom class loader is used.
+ */
+ @Test
+ public void wrongInstrumentDetection_shouldRaiseLinkageError() {
+ final Result result = JUnitCore.runClasses(TestWithCustomRunner.class);
+ assertThat(result.getRunCount(), equalTo(1));
+ assertThat(result.getFailureCount(), equalTo(1));
+
+ // check whether it's a linkage error
+ final StringWriter buffer = new StringWriter();
+ result.getFailures().get(0).getException().printStackTrace(new PrintWriter(buffer));
+ final int linkageErrorNameIndex = buffer.toString().indexOf(LinkageError.class.getName());
+ assertTrue(linkageErrorNameIndex >= 0);
+ }
+
+ /**
+ * Propper behavior test.
+ */
+ @Test
+ public void customizeInstumentDetection_shouldPass() {
+ final Result result = JUnitCore.runClasses(TestWithCustomRunnerThatWillPass.class);
+ assertThat(result.getRunCount(), equalTo(1));
+ assertThat(result.getFailureCount(), equalTo(0));
+ }
+
+}

0 comments on commit b6a3c55

Please sign in to comment.