Giter Site home page Giter Site logo

robolectric / robolectric Goto Github PK

View Code? Open in Web Editor NEW
5.8K 5.8K 1.4K 57.58 MB

Android Unit Testing Framework

Home Page: http://robolectric.org

License: Other

Java 99.14% Shell 0.19% Groovy 0.18% Starlark 0.01% Kotlin 0.48%
android java robolectric unit-testing

robolectric's Introduction

Build Status GitHub release

Robolectric is the industry-standard unit testing framework for Android. With Robolectric, your tests run in a simulated Android environment inside a JVM, without the overhead and flakiness of an emulator. Robolectric tests routinely run 10x faster than those on cold-started emulators.

Robolectric supports running unit tests for 14 different versions of Android, ranging from Lollipop (API level 21) to U (API level 34).

Usage

Here's an example of a simple test written using Robolectric:

@RunWith(AndroidJUnit4.class)
public class MyActivityTest {

  @Test
  public void clickingButton_shouldChangeResultsViewText() {
    Activity activity = Robolectric.setupActivity(MyActivity.class);

    Button button = (Button) activity.findViewById(R.id.press_me_button);
    TextView results = (TextView) activity.findViewById(R.id.results_text_view);

    button.performClick();
    assertThat(results.getText().toString(), equalTo("Testing Android Rocks!"));
  }
}

For more information about how to install and use Robolectric on your project, extend its functionality, and join the community of contributors, please visit http://robolectric.org.

Install

Starting a New Project

If you'd like to start a new project with Robolectric tests you can refer to deckard (for either maven or gradle) as a guide to setting up both Android and Robolectric on your machine.

build.gradle:

testImplementation "junit:junit:4.13.2"
testImplementation "org.robolectric:robolectric:4.13"

Building And Contributing

Robolectric is built using Gradle. Both IntelliJ and Android Studio can import the top-level build.gradle file and will automatically generate their project files from it.

To get a high-level overview of Robolectric's architecture, check out ARCHITECTURE.md.

Prerequisites

See Building Robolectric for more details about setting up a build environment for Robolectric.

Building

Robolectric supports running tests against multiple Android API levels. The work it must do to support each API level is slightly different, so its shadows are built separately for each. To build shadows for every API version, run:

./gradlew clean assemble testClasses --parallel

Testing

Run tests for all API levels:

The fully tests could consume more than 16G memory(total of physical and virtual memory).

./gradlew test --parallel

Run tests for part of supported API levels, e.g. run tests for API level 26, 27, 28:

./gradlew test --parallel "-Drobolectric.enabledSdks=26,27,28"

Run compatibility test suites on opening Emulator:

./gradlew connectedCheck

Using Snapshots

If you would like to live on the bleeding edge, you can try running against a snapshot build. Keep in mind that snapshots represent the most recent changes on master and may contain bugs.

build.gradle:

repositories {
    maven { url "https://oss.sonatype.org/content/repositories/snapshots" }
}
dependencies {
    testImplementation "org.robolectric:robolectric:4.14-SNAPSHOT"
}

robolectric's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

robolectric's Issues

How can I test classes that use Roboguice 1.1?

Some days ago I was using Roboguice 1.0 and was working fine (using the InjectedTestRunner.java, taken from the RoboSamples). But, with Roboguice 1.0 it seems to be impossible. This is what I get when trying to run my tests:

com.google.inject.CreationException: Guice creation errors:

1) Error injecting constructor, java.lang.NullPointerException
  at roboguice.util.Ln$BaseConfig.<init>(Unknown Source)
  while locating roboguice.util.Ln$BaseConfig
    for field at roboguice.util.Ln.config(Unknown Source)

1 error
    at com.google.inject.internal.Errors.throwCreationExceptionIfErrorsExist(Errors.java:354)
    at com.google.inject.InjectorBuilder.injectDynamically(InjectorBuilder.java:173)
    at com.google.inject.InjectorBuilder.build(InjectorBuilder.java:113)
    at com.google.inject.Guice.createInjector(Guice.java:92)
    at roboguice.application.RoboApplication.createInjector(RoboApplication.java:143)
    at roboguice.application.RoboApplication.getInjector(RoboApplication.java:84)
    at com.alwaysonmessage.temenos.activities.InjectedTestRunner.prepareTest(InjectedTestRunner.java:41)
    at com.xtremelabs.robolectric.RobolectricTestRunner.createTest(RobolectricTestRunner.java:277)
    at com.xtremelabs.robolectric.RobolectricTestRunner.createTest(RobolectricTestRunner.java:274)
    at org.junit.runners.BlockJUnit4ClassRunner$1.runReflectiveCall(BlockJUnit4ClassRunner.java:251)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:248)
    at com.xtremelabs.robolectric.RobolectricTestRunner.methodBlock(RobolectricTestRunner.java:215)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.NullPointerException
    at roboguice.util.Ln$BaseConfig.<init>(Ln.java:217)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at com.google.inject.DefaultConstructionProxyFactory$1.newInstance(DefaultConstructionProxyFactory.java:81)
    at com.google.inject.ConstructorInjector.construct(ConstructorInjector.java:85)
    at com.google.inject.ConstructorBindingImpl$Factory.get(ConstructorBindingImpl.java:111)
    at com.google.inject.SingleFieldInjector.inject(SingleFieldInjector.java:56)
    at com.google.inject.InjectionRequestProcessor$StaticInjection$1.call(InjectionRequestProcessor.java:109)
    at com.google.inject.InjectionRequestProcessor$StaticInjection$1.call(InjectionRequestProcessor.java:106)
    at com.google.inject.InjectorImpl.callInContext(InjectorImpl.java:804)
    at com.google.inject.InjectionRequestProcessor$StaticInjection.injectMembers(InjectionRequestProcessor.java:106)
    at com.google.inject.InjectionRequestProcessor.injectMembers(InjectionRequestProcessor.java:74)
    at com.google.inject.InjectorBuilder.injectDynamically(InjectorBuilder.java:168)
    ... 25 more

The problem seems to be in a new utility class called Ln but I'm not sure how to solve it. Could you guys give me a hand, please?

In Menu.xml, <item></item> not supported

This arose from trying to run Roboguice on some existing code. It appears to not support nested menus, but even barfs on just a single non-atomic like this:

<item
    android:title = "@string/xxx_text"
    android:icon = "@drawable/xxx_icon" ></item>

but this will work:

<item
    android:title = "@string/xxx_text"
    android:icon = "@drawable/xxx_icon" />

In RC1, Roboguice just hung up for me and never ended the test. In 0.9.8 you'll get an error like this:

java.lang.RuntimeException: java.lang.RuntimeException: [item: null]
at com.xtremelabs.robolectric.res.ResourceLoader.init(ResourceLoader.java:85)
at com.xtremelabs.robolectric.res.ResourceLoader.getStringValue(ResourceLoader.java:133)
at com.xtremelabs.robolectric.shadows.ShadowResources.getString(ShadowResources.java:53)
at android.content.res.Resources.getString(Resources.java)
at com....test1.shouldHaveApplicationName(test1.java:23)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at com.xtremelabs.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:208)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.RuntimeException: [item: null]
at com.xtremelabs.robolectric.res.MenuLoader.processNode(MenuLoader.java:67)
at com.xtremelabs.robolectric.res.MenuLoader.processChildren(MenuLoader.java:47)
at com.xtremelabs.robolectric.res.MenuLoader.processResourceXml(MenuLoader.java:38)
at com.xtremelabs.robolectric.res.DocumentLoader.loadResourceXmlFile(DocumentLoader.java:46)
at com.xtremelabs.robolectric.res.DocumentLoader.loadResourceXmlDir(DocumentLoader.java:40)
at com.xtremelabs.robolectric.res.DocumentLoader.loadResourceXmlDirs(DocumentLoader.java:30)
at com.xtremelabs.robolectric.res.ResourceLoader.init(ResourceLoader.java:79)
at com.xtremelabs.robolectric.res.ResourceLoader.getStringValue(ResourceLoader.java:133)
at com.xtremelabs.robolectric.shadows.ShadowResources.getString(ShadowResources.java:53)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.xtremelabs.robolectric.bytecode.ShadowWrangler.methodInvoked(ShadowWrangler.java:87)
at com.xtremelabs.robolectric.bytecode.RobolectricInternals.methodInvoked(RobolectricInternals.java:110)
at android.content.res.Resources.getString(Resources.java)
at com....test1.shouldHaveApplicationName(test1.java:23)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
... 19 more

ShadowSQLiteCursor.getString() throws ClassCastException for INTEGER type values

I was writing a Database Exporter where I simply called cursor.getString() for column values of any type other than BLOB. It works fine, but when testing the code with robolectric, the following exception was thrown for an INTEGER type value:

java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
    at com.xtremelabs.robolectric.shadows.ShadowSQLiteCursor.getString(ShadowSQLiteCursor.java:117)
        .............

Peeking into the source of ShadowSQLiteCursor, I found out the implementation of the getString() method as follows:

public String getString(int columnIndex) {
        checkPosition();
        Object value = this.currentRow.get(getColumnNames()[columnIndex]);
        if (value instanceof Clob) {
            try {
                return ((Clob) value).getSubString(1, (int)((Clob) value).length());
            } catch (SQLException x) {
                throw new RuntimeException(x);
            }
        } else {
            return (String)value;
        }
}

Note that in the last return statement, the value is casted to String which throws the ClassCastException for INTEGER type values. Now, in the source of Android 1.6, the implementation of the MatrixCursor.getString() method is as follows:

public String getString(int column) {
        Object value = get(column);
        if (value == null) return null;
        return value.toString();
}

Here, the value.toString() is called which would work fine for both INTEGER and FLOAT type values.

Therefore, I think the ShadowSQLiteCursor.getString() should return value.toString() instead of (String) value.

findViewById() returns null in onPrepareDialog()

findViewById called via given Dialog returns null (works in Android):

Example:

protected void onPrepareDialog(int id, Dialog dialog) {
    TextView sizeOfProject = (TextView) dialog.findViewById(R.id.dialog_upload_size_of_project);
    sizeOfProject.setText("blah");
}

this will lead to a "java.lang.IllegalStateException: Could not execute method of the activity" because of the returned null

Maven cannot find artifact com.google.android.maps:maps

I'm trying to build Robolectric with Maven, but all I'm getting is:

Build errors for robolectric; org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal on project robolectric: Could not resolve dependencies for project com.pivotallabs:robolectric:jar:1.0-RC2-SNAPSHOT: Failure to find com.google.android.maps:maps:jar:9_r1 in http://repo1.maven.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced

I checked Maven Central and it's indeed not there, not in any other version either.

Am I missing a repository or should it be on central?

Is it possible to test TabActivites?

I'd like to test code which runs on a TabActivity but I a Runtime error while executing the unit test. It seems that the inflation process doesn't work:

java.lang.RuntimeException: error inflating layout/tabs
    at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:99)
    at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:77)
    at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:81)
    at com.xtremelabs.robolectric.res.ResourceLoader.inflateView(ResourceLoader.java:104)
    at com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:38)
    at com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:43)
    at android.view.LayoutInflater.inflate(LayoutInflater.java)
    at com.xtremelabs.robolectric.shadows.ShadowActivity.setContentView(ShadowActivity.java:68)
    at android.app.Activity.setContentView(Activity.java)
    at com.alwaysonmessage.temenos.activities.TemenosTabs.onCreate(TemenosTabs.java:19)
    at com.alwaysonmessage.temenos.activities.TemenosTabsTest.shouldHum(TemenosTabsTest.java:36)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at com.xtremelabs.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:220)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.constructView(ViewLoader.java:159)
    at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.create(ViewLoader.java:142)
    at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:124)
    at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:97)
    at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:77)
    at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:81)
    at com.xtremelabs.robolectric.res.ResourceLoader.inflateView(ResourceLoader.java:104)
    at com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:38)
    at com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:43)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.xtremelabs.robolectric.bytecode.ShadowWrangler.methodInvoked(ShadowWrangler.java:78)
    at com.xtremelabs.robolectric.bytecode.RobolectricInternals.methodInvoked(RobolectricInternals.java:50)
    at android.view.LayoutInflater.inflate(LayoutInflater.java)
    at com.xtremelabs.robolectric.shadows.ShadowActivity.setContentView(ShadowActivity.java:68)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.xtremelabs.robolectric.bytecode.ShadowWrangler.methodInvoked(ShadowWrangler.java:78)
    at com.xtremelabs.robolectric.bytecode.RobolectricInternals.methodInvoked(RobolectricInternals.java:50)
    at android.app.Activity.setContentView(Activity.java)
    at com.alwaysonmessage.temenos.activities.TemenosTabs.onCreate(TemenosTabs.java:19)
    at com.alwaysonmessage.temenos.activities.TemenosTabsTest.shouldHum(TemenosTabsTest.java:36)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    ... 20 more
Caused by: java.lang.NullPointerException
    at com.xtremelabs.robolectric.internal.TestAttributeSet.getAttributeResourceValue(TestAttributeSet.java:86)
    at com.xtremelabs.robolectric.shadows.ShadowView.applyIdAttribute(ShadowView.java:579)
    at com.xtremelabs.robolectric.shadows.ShadowView.__constructor__(ShadowView.java:68)
    at android.widget.TabHost.<init>(TabHost.java)
    at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.constructView(ViewLoader.java:159)
    at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.create(ViewLoader.java:142)
    at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:124)
    at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:97)
    at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:77)
    at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:81)
    at com.xtremelabs.robolectric.res.ResourceLoader.inflateView(ResourceLoader.java:104)
    at com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:38)
    at com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:43)
    at android.view.LayoutInflater.inflate(LayoutInflater.java)
    at com.xtremelabs.robolectric.shadows.ShadowActivity.setContentView(ShadowActivity.java:68)
    at android.app.Activity.setContentView(Activity.java)
    at com.alwaysonmessage.temenos.activities.TemenosTabs.onCreate(TemenosTabs.java:19)
    at com.alwaysonmessage.temenos.activities.TemenosTabsTest.shouldHum(TemenosTabsTest.java:36)
    ... 20 more

I guess Robolectric does not support this yet... will this be included someday? is there any other way to test this kind of classes?

Thanks.

ShadowPreferenceActivity does not support findViewById(android.R.id.content)

In the onCreate(...) we obtain the default FrameLayout from Android via this call:

final FrameLayout layout = (FrameLayout) findViewById(android.R.id.content);

However, when findViewById(android.R.id.content) is executed a null is returned. However, at runtime, the real FrameLayout is returned.

Expected results: findViewById(android.R.id.content) should return a valid FrameLayout.

Not able to inflate a fragment

Pretty simple:

LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
inflater.inflate(layoutId, null);

The layoutId I'm passing resolves to:

<RelativeLayout
   >
    <fragment
        android:id="@+id/vehicleSummaryFragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        class="com.my.package.RandomFragment" />

The error is :

Caused by: java.lang.RuntimeException: couldn't find view class fragment

The error seems to be caused by the pickViewMethod() method in the class: com.xtremelabs.robolectric.res.ViewLoader.java

The pickViewMethod() to resolve the fragment in the above XML should reference the class attribute I assume?

UriMatcher does not work

UriMatcher fails with always returning 0 even if no Uris added. See attached test.

@RunWith(RobolectricTestRunner.class)
public class UriMatcherTest {
@test
public void testURIMatcherDefault() throws Exception {
UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
Assert.assertEquals(UriMatcher.NO_MATCH, matcher.match(Uri.EMPTY));
}
}

pom.xml is incorrect

There is an issue with the dependecy for httpclient.
I will provide a pull request in a sec.

h2 expects a GROUP BY to accompany min / max operators while SQLite does not

Try the following in h2 vs SQLite. All will pass in SQLite, but some will the last one will fail in h2:

create table if not exists test(id integer, value integer);
select id, value from test;
select id, max(value) from test group by id;
select id, max(value) from test;

Failure:
Column "ID" must be in the GROUP BY list; SQL statement:
select id, max(value) from test [90016-147] 90016/90016

Implement SQLiteDatabase.compileStatement

The method with signature:
public android.database.sqlite.SQLiteStatement compileStatement(java.lang.String sql) throws android.database.SQLException
Is currently not shadowed. Prepared statements are a universal best practice, so I bet many application use them, so I think shadowing this method would be generally helpful. It is also required to use ORMLite.

Building code

Hi, I forked your repository and am now attempting to build your code. I linked to Maps v7 and tried Android 2.1, 8, and 9, but no matter which I choose, I am still getting the following compilation errors:
LogFactory cannot be resolved ShadowDefaultRequestDirector.java /robolectric/src/com/xtremelabs/robolectric/shadows line 91 Java Problem
The import org.apache.commons.logging.LogFactory cannot be resolved ShadowDefaultRequestDirector.java /robolectric/src/com/xtremelabs/robolectric/shadows line 8 Java Problem

Thanks!

Using Robolectric with Junit @Parameterized

Hi guys,

This is not really an issue, rather a kind of contribution. It's not clean enough so that I can make a fork / pull request, but it layouts the main idea, and maybe someone will be willing to do something with this.

Main idea : being able to used Parameterized tests with Robolectric.

Here are the issues :

  • Parameterized is a custom runner, in fact it's a test Suite that generates one test runner for each set of data. Those test runners are subclasses of BlockJUnit4ClassRunner, and Robolectric need the runner to be an instance of RobolectricTestRunner in order to use its custom classloader
  • Parameterized passes the test data through the test constructor. Robolectric requires an empty constructor.
  • I had to do a bit of reflection to access Robolectric classloader. The method that generates the data is static and must be called from a class loaded by the Robolectric classloader.

The solution I found was to copy the Parameterized runner, and then hack around it to use RobolectricTestRunner.

Instead of passing the arguments through the constructor, you need to implement an init() method, with a matching number of arguments.

I needed to use my custom subclass of RobolectricTestRunner, which sets the project path, and that's mainly why I can't directly contribute this code. I don't really like the current implementation, because even if you integrate it, there will be no easy way to customize RobolectricParameterized.. unless you guys have some clever idea :) .

No more talking, let's dive into the code :

ShadowView#getLayoutParams is broken, or the parsing thereof

I am trying to make assertions against a view's layout params, and was wondering why it always came back as 0. Then I found this line in ShadowView:

    private ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(0, 0);

I guess that's why :-) Any reason why layout params are not being parsed like any other view attribute? Is this a bug or has this simply not been implemented yet? It makes testing your layouts fairly pointless.

Background: I am trying to write a regression test for a widget that we wrote where I want to assert that certain view attributes are only being applied to the view container, not the child view (for example, any layout_* attributes).

Size of Integer in h2 is different than in SQLite

When you create a table column using the keyword INTEGER, this is interpreted by h2 as an INTEGER(10), however SQLite dynamically changes the size of the INTEGER to fit the data from 1 to 8 bytes in size. This is a LONG or BIGINT(19) in h2.

I fixed this by creating a mapping in the execSQL statement that maps INTEGER to BIGINT(19) (case-insensitively, of course.)

Please see my pull request.

RobolectricClassLoader not load android.content.ServiceConnection in 1.0-RC4

I've tested this in 0.9.4, 1.0-RC4, 1.0-RC5 and 1.5-SNAPSHOT, RobolectricClassLoader load android.content.ServiceConnection properly in 0.9.4 but not in 1.0-RC4, 1.0-RC5 and 1.5-SNAPSHOT.

My activity class looks like this:
public class SampleActivity extends Activity {
protected SampleServiceBinder serviceBinder;
protected ServiceConnection serviceConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
serviceBinder = (SampleServiceBinder) service;
}
public void onServiceDisconnected(ComponentName className) {
if (serviceBinder != null) {
serviceBinder = null;
}
}
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
bindService(new Intent(this, SampleService.class),
serviceConnection, Context.BIND_AUTO_CREATE);
}
}

My simple activity test:
@RunWith(RobolectricTestRunner.class)
public class LiveTVControlActivityTest {
private SampleActivity sampleActivity;
@before
public void setUp() throws Exception {
sampleActivity = new sampleActivity(); // add break point here and debug
assertNotNull(sampleActivity);
sampleActivity.onCreate(null);
}
}

I've debugged step by step at break point, in 1.0-RC4 and 1.0-RC5, the
ServiceConnection implemented in my SampleActivity is ignored by
RobolectricClassLoader, so at later stage in SampleActivity where use
serviceBinder.doSomething(), I've got a null pointer exception. The same
test cod works in 0.9.4

SQLiteQueryBuilders' usage of rawQueryWithFactory not supported

When using the SQLiteQueryBuilder.query() method (example below) a null cursor is returned because there is no shadow implementation of the SQLiteDatabase.rawQueryWithFactory() method in ShadowSQLiteDatabase class. This means SQLiteQueryBuilder is not really usable with the ShadowImplementation of SQLiteOpenHelper.

With this usage of SQLiteQueryBuilder the value returned to cursor is null.

    final SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
    qb.setTables(table);
    Cursor cursor = qb.query(db, columns, selection, selectionArgs, groupBy, having, sortOrder);

The method below is called in SQLiteQueryBuilder's query method is called (Line: 316 in Android source), the last statement rawQueryWithFactory calls a method in SQLiteDatabase.

       public Cursor query(SQLiteDatabase db, String[] projectionIn,
            String selection, String[] selectionArgs, String groupBy,
            String having, String sortOrder, String limit) {
        if (mTables == null) {
            return null;
        }

        String sql = buildQuery(
                projectionIn, selection, groupBy, having,
                sortOrder, limit);

        if (Log.isLoggable(TAG, Log.DEBUG)) {
            Log.d(TAG, "Performing query: " + sql);
        }
        return db.rawQueryWithFactory(
                mFactory, sql, selectionArgs,
                SQLiteDatabase.findEditTable(mTables));
    }

This method is called in SQLiteDatabase (Line: 1399 in Android source) and not overridden in ShadowSQLiteDatabase. The result is a null returned instead of a cursor.

    public Cursor rawQueryWithFactory(
            CursorFactory cursorFactory, String sql, String[] selectionArgs,
            String editTable) {
        if (!isOpen()) {
            throw new IllegalStateException("database not open");
        }
        BlockGuard.getThreadPolicy().onReadFromDisk();
        long timeStart = 0;

        if (Config.LOGV || mSlowQueryThreshold != -1) {
            timeStart = System.currentTimeMillis();
        }

        SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable);

        Cursor cursor = null;
        try {
            cursor = driver.query(
                    cursorFactory != null ? cursorFactory : mFactory,
                    selectionArgs);
        } finally {
            if (Config.LOGV || mSlowQueryThreshold != -1) {

                // Force query execution
                int count = -1;
                if (cursor != null) {
                    count = cursor.getCount();
                }

                long duration = System.currentTimeMillis() - timeStart;

                if (Config.LOGV || duration >= mSlowQueryThreshold) {
                    Log.v(SQLiteCursor.TAG,
                          "query (" + duration + " ms): " + driver.toString() + ", args are "
                                  + (selectionArgs != null
                                  ? TextUtils.join(",", selectionArgs)
                                  : "<null>")  + ", count is " + count);
                }
            }
        }
        return cursor;
    }

Inflating ListViews fails with an internal exception

Having a ListView in your layouts will break Robolectric's ViewLoader.inflateView:

RuntimeException: error inflating layout/main

The exception is thrown in ViewLoader.ViewNode.constructView, when trying to invoke the ListView's ctor using newInstance. The cause is an InvocationTargetException, but there is no extra info attached about the cause.

I have a minimal Android and RL test project which reproduces the issue, if you want me to send it along.

Robolectric.application.getResources().getString(); doesn't fetch string.

While trying to fetch a string resource from my project, calling:

String blah = Robolectric.application.getResources().getString(R.id.blah);

query ends up null after this call. The resource in question works in the activity it's being called from, but when I try to use it in my testing environment, I can't seem to get to it. The normal way in Android is using Activity.getResources().getString(), so I figured it would work the same in Robolectric. Simple misunderstanding on my behalf, or legitimate bug?

java.lang.NoClassDefFoundError: android/bluetooth/BluetoothAdapter for Android 1.5 project

Running a Robolectric unit test for an Android 1.5 project throws an exception:

java.lang.NoClassDefFoundError: android/bluetooth/BluetoothAdapter
at com.xtremelabs.robolectric.shadows.ShadowApplication.(ShadowApplication.java:67)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at java.lang.Class.newInstance0(Class.java:355)
at java.lang.Class.newInstance(Class.java:308)
at com.xtremelabs.robolectric.bytecode.ShadowWrangler.shadowFor(ShadowWrangler.java:163)
at com.xtremelabs.robolectric.bytecode.ShadowWrangler$InvocationPlan.prepare(ShadowWrangler.java:311)
at com.xtremelabs.robolectric.bytecode.ShadowWrangler.methodInvoked(ShadowWrangler.java:81)
at com.xtremelabs.robolectric.bytecode.RobolectricInternals.methodInvoked(RobolectricInternals.java:110)
at android.content.Context.(Context.java)
at android.content.ContextWrapper.(ContextWrapper.java)
at android.app.Application.(Application.java)
at com.xtremelabs.robolectric.Robolectric.resetStaticState(Robolectric.java:303)
at com.xtremelabs.robolectric.RobolectricTestRunner.setupApplicationState(RobolectricTestRunner.java:275)
at com.xtremelabs.robolectric.RobolectricTestRunner.internalBeforeTest(RobolectricTestRunner.java:221)
at com.xtremelabs.robolectric.RobolectricTestRunner.methodBlock(RobolectricTestRunner.java:201)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.ClassNotFoundException: caught an exception while obtaining a class file for android.bluetooth.BluetoothAdapter
at javassist.Loader.findClass(Loader.java:359)
at com.xtremelabs.robolectric.bytecode.RobolectricClassLoader.findClass(RobolectricClassLoader.java:60)
at javassist.Loader.loadClass(Loader.java:311)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at com.xtremelabs.robolectric.bytecode.RobolectricClassLoader.loadClass(RobolectricClassLoader.java:37)
... 33 more
Caused by: com.xtremelabs.robolectric.bytecode.IgnorableClassNotFoundException: msg because of javassist.NotFoundException: android.bluetooth.BluetoothAdapter
at com.xtremelabs.robolectric.bytecode.AndroidTranslator.onLoad(AndroidTranslator.java:80)
at javassist.Loader.findClass(Loader.java:340)
... 37 more

Background drawable in style causes crash...it is looked up as color

I've got a stylized button that sets the background to a drawable via a style:

<style name="helpButton" parent="serif.white.14.italic">
    <item name="android:layout_height">20dp</item>
    <item name="android:layout_width">20dp</item>
    <item name="android:background">@drawable/help</item>
</style>

and is applied as follows:

            <Button
                style="@style/helpButton"
                android:layout_margin="14dp"
                android:gravity="center"
                android:onClick="showHelp"/>

this works fine in android, but the shadow inflater gets a NPE:

java.lang.RuntimeException: error inflating layout/attendance_stats_by_roster
...
Caused by: java.lang.NullPointerException
at com.xtremelabs.robolectric.res.ColorResourceLoader.getValue(ColorResourceLoader.java:33)
at com.xtremelabs.robolectric.res.ResourceLoader.getColorValue(ResourceLoader.java:341)
at com.xtremelabs.robolectric.shadows.ShadowResources.getColor(ShadowResources.java:66)
at android.content.res.Resources.getColor(Resources.java)
at com.xtremelabs.robolectric.shadows.ShadowView.setBackgroundColor(ShadowView.java:243)
at com.xtremelabs.robolectric.shadows.ShadowButton.applyAttributes(ShadowButton.java:14)
at com.xtremelabs.robolectric.shadows.ShadowView.constructor(ShadowView.java:90)
at com.xtremelabs.robolectric.shadows.ShadowView.constructor(ShadowView.java:82)

It looks as if the inflator is assuming the background is always a color.

NullPointer in ColorResourceLoader

I have xml layout that includes a merge. It works fine on the device but when try to unit test the associated activity it fails with a NullPointerException.

java.lang.RuntimeException: error inflating layout/filter_choice
at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:106)
at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:82)
at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:86)
at com.xtremelabs.robolectric.res.ResourceLoader.inflateView(ResourceLoader.java:336)
at com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:43)
at com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:48)
at android.view.LayoutInflater.inflate(LayoutInflater.java)
at com.xtremelabs.robolectric.shadows.ShadowActivity.setContentView(ShadowActivity.java:102)
at android.app.Activity.setContentView(Activity.java)
at ie.shizzle.events.filter.Filter.onCreate(Filter.java:63)
at test.ie.shizzle.filter.TestFilter.setup(TestFilter.java:21)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
at com.xtremelabs.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:264)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:46)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.RuntimeException: error inflating layout/buttons
at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:106)
at com.xtremelabs.robolectric.res.ViewLoader.access$100(ViewLoader.java:27)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.create(ViewLoader.java:152)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:133)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:136)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:136)
at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:102)
at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:82)
at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:86)
at com.xtremelabs.robolectric.res.ResourceLoader.inflateView(ResourceLoader.java:336)
at com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:43)
at com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:48)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at com.xtremelabs.robolectric.bytecode.ShadowWrangler.methodInvoked(ShadowWrangler.java:100)
at com.xtremelabs.robolectric.bytecode.RobolectricInternals.methodInvoked(RobolectricInternals.java:111)
at android.view.LayoutInflater.inflate(LayoutInflater.java)
at com.xtremelabs.robolectric.shadows.ShadowActivity.setContentView(ShadowActivity.java:102)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at com.xtremelabs.robolectric.bytecode.ShadowWrangler.methodInvoked(ShadowWrangler.java:100)
at com.xtremelabs.robolectric.bytecode.RobolectricInternals.methodInvoked(RobolectricInternals.java:111)
at android.app.Activity.setContentView(Activity.java)
at ie.shizzle.events.filter.Filter.onCreate(Filter.java:63)
at test.ie.shizzle.filter.TestFilter.setup(TestFilter.java:21)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
... 20 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:532)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.constructView(ViewLoader.java:178)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.create(ViewLoader.java:158)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:133)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:136)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:136)
at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:102)
... 52 more
Caused by: java.lang.NullPointerException
at com.xtremelabs.robolectric.res.ColorResourceLoader.getValue(ColorResourceLoader.java:33)
at com.xtremelabs.robolectric.res.ResourceLoader.getColorValue(ResourceLoader.java:341)
at com.xtremelabs.robolectric.shadows.ShadowResources.getColor(ShadowResources.java:65)
at android.content.res.Resources.getColor(Resources.java)
at com.xtremelabs.robolectric.shadows.ShadowView.setBackgroundColor(ShadowView.java:244)
at com.xtremelabs.robolectric.shadows.ShadowButton.applyAttributes(ShadowButton.java:14)
at com.xtremelabs.robolectric.shadows.ShadowView.constructor(ShadowView.java:90)
at com.xtremelabs.robolectric.shadows.ShadowView.constructor(ShadowView.java:82)
at android.widget.Button.(Button.java)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.constructView(ViewLoader.java:178)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.create(ViewLoader.java:158)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:133)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:136)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:136)
at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:102)
at com.xtremelabs.robolectric.res.ViewLoader.access$100(ViewLoader.java:27)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.create(ViewLoader.java:152)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:133)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:136)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:136)
at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:102)
at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:82)
at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:86)
at com.xtremelabs.robolectric.res.ResourceLoader.inflateView(ResourceLoader.java:336)
at com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:43)
at com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:48)
at android.view.LayoutInflater.inflate(LayoutInflater.java)
at com.xtremelabs.robolectric.shadows.ShadowActivity.setContentView(ShadowActivity.java:102)
at android.app.Activity.setContentView(Activity.java)
at ie.shizzle.events.filter.Filter.onCreate(Filter.java:63)
at test.ie.shizzle.filter.TestFilter.setup(TestFilter.java:21)
... 20 more

I am using robolectric-1.0-RC5-20110908.172630-48-jar-with-dependencies.jar and looking at the source it appears to be an unboxing error at ColorResourceLoader.java:33. If colorResolver.getValue(resourceName) return a null then there will be a NullPointerException thrown. I'm not sure if this should ever return null but in my case the resourceName = "android:color/transparent"

RobolectricTestRunner's use of ClassLoader breaks Mockito when package private mocks are shared

RobolectricTestRunner has several issues with its use of a custom class loader:

  1. It changes the class loader in it's constructor (which can be run long before the class's tests are run - other tests can run in between)
  2. It never resets the class loader

This behavior manifests itself when two test classes (one Robolectric, one Mockito) both mock the same package-private class/interface. When this occurs, the Mockito class will fail.

Below is a workaround RobolectricTestRunner that resolves the issue by:

  1. Capturing the default/robolectric class loader in the constructor
  2. Resetting the default class loader after the RobolectricTestRunner constructor has run
  3. Setting the robolectric class loader before the tests for that class are run
  4. Resetting the default class loader after the tests for that class are run
public class RobolectricTestRunnerClassLoaderFix extends BlockJUnit4ClassRunner {
    private final BlockJUnit4ClassRunner delegate;

    private final ClassLoader defaultClassLoader;
    private final ClassLoader robolectricClassLoader;

    public RobolectricTestRunnerClassLoaderFix(final Class<?> testClass) throws InitializationError {
        super(testClass);

        // "Default" class loader
        defaultClassLoader = Thread.currentThread().getContextClassLoader();

        delegate = new RobolectricTestRunner(testClass);

        // "Robolectric" class loader
        robolectricClassLoader = Thread.currentThread().getContextClassLoader();

        // Loaders are constructed before _any_ tests are run, which may not start with robolectric ones
        resetClassLoader();
    }

    private void resetClassLoader() {
        Thread.currentThread().setContextClassLoader(defaultClassLoader);
    }

    @Override
    public boolean equals(Object obj) {
        return delegate.equals(obj);
    }

    @Override
    public Description getDescription() {
        return delegate.getDescription();
    }

    @Override
    public void filter(Filter filter) throws NoTestsRemainException {
        delegate.filter(filter);
    }

    @Override
    public int hashCode() {
        return delegate.hashCode();
    }

    @Override
    public int testCount() {
        return delegate.testCount();
    }

    @Override
    public void run(RunNotifier notifier) {

        try {
            Thread.currentThread().setContextClassLoader(robolectricClassLoader);

            delegate.run(notifier);
        } finally {
            resetClassLoader();
        }
    }

    @Override
    public void sort(Sorter sorter) {
        delegate.sort(sorter);
    }

    @Override
    public void setScheduler(RunnerScheduler scheduler) {
        delegate.setScheduler(scheduler);
    }

    @Override
    public String toString() {
        return delegate.toString();
    }

}

Spinners bug out on setAdapter with current HEAD

I had some code that was fine with 0.9.4, but started bugging out during a setAdapter() call with the current HEAD. I've managed to narrow it down to a simple test case (commit implementing this is at palfrey@d383cd5) which bugs out as follows:

Testcase: checkSetAdaptor took 0.034 sec
Caused an ERROR
can't get a shadow for null
java.lang.NullPointerException: can't get a shadow for null
at com.xtremelabs.robolectric.Robolectric.shadowOf_(Robolectric.java:552)
at com.xtremelabs.robolectric.Robolectric.shadowOf(Robolectric.java:415)
at com.xtremelabs.robolectric.shadows.ShadowViewGroup.addView(ShadowViewGroup.java:41)
at com.xtremelabs.robolectric.shadows.ShadowAdapterView.update(ShadowAdapterView.java:141)
at com.xtremelabs.robolectric.shadows.ShadowAdapterView.access$100(ShadowAdapterView.java:17)
at com.xtremelabs.robolectric.shadows.ShadowAdapterView$1.run(ShadowAdapterView.java:43)
at com.xtremelabs.robolectric.util.Scheduler.postDelayed(Scheduler.java:31)
at com.xtremelabs.robolectric.shadows.ShadowLooper.post(ShadowLooper.java:98)
at com.xtremelabs.robolectric.shadows.ShadowHandler.postDelayed(ShadowHandler.java:40)
at com.xtremelabs.robolectric.shadows.ShadowHandler.post(ShadowHandler.java:35)
at android.os.Handler.post(Handler.java)
at com.xtremelabs.robolectric.shadows.ShadowAdapterView.invalidateAndScheduleUpdate(ShadowAdapterView.java:39)
at com.xtremelabs.robolectric.shadows.ShadowAdapterView.setAdapter(ShadowAdapterView.java:33)
at com.xtremelabs.robolectric.shadows.ShadowAbsSpinner.setAdapter(ShadowAbsSpinner.java:13)
at android.widget.AbsSpinner.setAdapter(AbsSpinner.java)
at com.xtremelabs.robolectric.shadows.AbsSpinnerTest.checkSetAdaptor(AbsSpinnerTest.java:41)
at com.xtremelabs.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:220)

ShadowFragment and ShadowFragmentActivity

Can you pull these two classes from Roboguice and add the dependency to the compatibility library v4 r4 and cut another release so we can take it out in Roboguice..

NullPointerException in TestAttributeSet

Here is the exception **

Here is the code:

class OverviewActivity extends ListActivity {
   public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.overview);

Here is the test code:

OverviewActivity overview = new OverviewActivity();
overview.onCreate(null);

Probably this problem is due to the fact that I've several components and a listview in one listactivity:

<LinearLayout>
     <TextView android:id="@+id/overview_text" ... />
    ...
    <ListView android:id="@id/android:list" ... />
</LinearLayout>

**
Caused by: java.lang.NullPointerException
at com.xtremelabs.robolectric.tester.android.util.TestAttributeSet.getAttributeResourceValue(TestAttributeSet.java:134)
at com.xtremelabs.robolectric.shadows.ShadowView.applyIdAttribute(ShadowView.java:672)
at com.xtremelabs.robolectric.shadows.ShadowView.applyAttributes(ShadowView.java:95)
at com.xtremelabs.robolectric.shadows.ShadowView.constructor(ShadowView.java:90)
at com.xtremelabs.robolectric.shadows.ShadowView.constructor(ShadowView.java:82)
at android.widget.ListView.(ListView.java)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.constructView(ViewLoader.java:178)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.create(ViewLoader.java:158)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:133)
at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:136)
at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:102)
at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:82)
at com.xtremelabs.robolectric.res.ViewLoader.inflateView(ViewLoader.java:86)
at com.xtremelabs.robolectric.res.ResourceLoader.inflateView(ResourceLoader.java:347)
at com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:43)
at com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:48)
at android.view.LayoutInflater.inflate(LayoutInflater.java)
at com.xtremelabs.robolectric.shadows.ShadowActivity.setContentView(ShadowActivity.java:105)
at android.app.Activity.setContentView(Activity.java)
at xy.activities.OverviewActivity.onCreate(OverviewActivity.java:52)

SQLiteDatabase test issues

I am trying to use your code with SQLite, but the tests are failing because in the CREATE TABLE statement on line 32 of SQLiteDatabaseTest you are using AUTO_INCREMENT instead of AUTOINCREMENT. Also, SQLite doesn't like INT instead of INTEGER.

Since you said you planned to support configuring between different databases, I thought you might want to know.

i.e.
statement.execute("CREATE TABLE table_name (id INT PRIMARY KEY AUTO_INCREMENT, first_column VARCHAR(255), second_column BINARY, name VARCHAR(255));");

should be:
statement.execute("CREATE TABLE table_name (id INTEGER PRIMARY KEY AUTOINCREMENT, first_column VARCHAR(255), second_column BINARY, name VARCHAR(255));");

Implement missing SQLiteDatabase methods to provide support for ORMLite

Since android.database.sqlite.SQLiteDatabase.rawQuery isn't implemented, it's currently not possible to test classes that use ORMLite.

For example will com.j256.ormlite.dao.BaseDaoImpl.query fail with a NullPointerException, because com.j256.ormlite.android.AndroidCompiledStatement.getCursor calls rawQuery at line 128:

java.lang.NullPointerException
    at com.j256.ormlite.android.AndroidCompiledStatement.getCursor(AndroidCompiledStatement.java:129)
    at com.j256.ormlite.android.AndroidCompiledStatement.runQuery(AndroidCompiledStatement.java:50)
    at com.j256.ormlite.stmt.SelectIterator.<init>(SelectIterator.java:52)
    at com.j256.ormlite.stmt.StatementExecutor.buildIterator(StatementExecutor.java:170)
    at com.j256.ormlite.stmt.StatementExecutor.query(StatementExecutor.java:120)
    at com.j256.ormlite.dao.BaseDaoImpl.query(BaseDaoImpl.java:179)

ORMLite might depend on other methods aswell, but this is the only one I've seen so far.

SQLiteCursor isAfterLast() causes infinite loop

I iterate my SQLiteDatabase cursor using this method:

    cursor.moveToFirst();
    while (cursor.isAfterLast() == false) {
        <read cursor data>
        cursor.moveToNext();
    }

Somehow, the cursor.isAfterLast() method always returns false, causing the while loop to execute indefinitely.

If I changed the cursor iteration to this, then it works:

    for (int i = 0; i < cursor.getCount(); i++) {
        cursor.moveToPosition(i);
                    <read cursor data>
    }

Is this because the ShadowSQLiteCursor does not implement isAfterLast() method?

Looper in ShadowHandler is Null when the Handler is created in a CustomApplication class

I have an Application class as following:

public final class MyApp extends RoboApplication {

private Handler startLoadingHandler = new Handler(new Handler.Callback() {

    public boolean handleMessage(final Message msg) {
        if (listener.getProgressDialog() != null) {
            try {
                listener.getProgressDialog().dismiss();
            } catch (RuntimeException ex) {
                Log.i("WhosAround",
                        "Can't dismiss dialog. It doesn't belong to any window");
            }

        }
        listener.setProgressDialog(ProgressDialog.show(
                getCurrentActivity(), "",
                getString(R.string.waitingConnection)));
        return true;
    }
});

}

Then I call this handler like:

startLoadingHandler.sendEmptyMessage(0);

postDelayed is being called and shadowOf(looper) is executed. Looper is null so it throws an exception.
The constructor method of the ShadowHandler is never called, I don't know why. I've tried this app in the emulator and in the cell and it does work. Do you know what could this be?

Thanks!

Maven support

I am starting a new android project with maven.
It would be cool to have robolectric as a dependency :)

ContextMenu

Is there any way to test context-menu?

Specifically, I bind my context menu to items of ListView using convertView.setOnCreateContextMenuListener(listener) on the actual code.
But robolectric does not seem to come with any implementation to handle this.

I tried, for example, to call showContextMenu() and createContextMenu(stubMenu) on the test. But neither one of them seems to do anything at all.

Thank you

Why use h2 when you can use SQLite?

I just finished building you code and running your tests and all of them passed. Then I made a few very simple changes:

  1. I pulled the jar SQLite JDBC jar from the following link and dropped it into your lib folder:
    http://www.zentus.com/sqlitejdbc/
  2. I changed the SQLiteDatabase to use this SQLite JDBC binding instead of h2:
    //Class.forName("org.h2.Driver").newInstance();
    Class.forName("org.sqlite.JDBC").newInstance();
    //connection = DriverManager.getConnection("jdbc:h2:mem:");
    connection = DriverManager.getConnection("jdbc:sqlite:mem:");
  3. I ran the tests again and all the SQLite related ones passed.

What advantage is there to using h2 when Android uses SQLite?

RuntimeException in ResourceLoader

Whenever we do a findViewById(), we get the stacktrace below. Creating a directory called xml under res makes our tests pass. It would be nice if we didn't need to have an xml directory, which our project doesn't use.


java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at com.xtremelabs.robolectric.shadows.ShadowDialog.show(ShadowDialog.java:106)
at android.app.Dialog.show(Dialog.java)
at com.shinyandroid.gui.DialogOpenerNew$1.run(DialogOpenerNew.java:21)
at com.xtremelabs.robolectric.util.Scheduler.postDelayed(Scheduler.java:31)
at com.xtremelabs.robolectric.util.Scheduler.post(Scheduler.java:36)
at com.xtremelabs.robolectric.shadows.ShadowActivity.runOnUiThread(ShadowActivity.java:168)
at android.app.Activity.runOnUiThread(Activity.java)
at com.shinyandroid.gui.DialogOpenerNew.run(DialogOpenerNew.java:16)
at com.shinyandroid.view.ActionableSprite.touchesEnded(ActionableSprite.java:26)
at com.shinyandroid.TouchHandlers.touchesEnded(TouchHandlers.java:26)
at com.shinyandroid.BaseMenuLayer.ccTouchesEnded(BaseMenuLayer.java:101)
at com.shinyandroid.test.TestHelper.upInRect(TestHelper.java:163)
at com.shinyandroid.test.TestHelper.touchInRect(TestHelper.java:145)
at com.shinyandroid.StoreMenuHelper.doTouch(StoreMenuHelper.java:15)
at com.shinyandroid.StoreMenuHelper.touchSidewalksButton(StoreMenuHelper.java:10)
at com.shinyandroid.MainMenuLayerTest.selectingSidewalkTypeClosesAllMenus(MainMenuLayerTest.java:118)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at com.xtremelabs.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:208)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.junit.runner.JUnitCore.run(JUnitCore.java:157)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:60)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.xtremelabs.robolectric.shadows.ShadowDialog.show(ShadowDialog.java:100)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.xtremelabs.robolectric.bytecode.ShadowWrangler.methodInvoked(ShadowWrangler.java:87)
at com.xtremelabs.robolectric.bytecode.RobolectricInternals.methodInvoked(RobolectricInternals.java:111)
at android.app.Dialog.show(Dialog.java)
at com.shinyandroid.gui.DialogOpenerNew$1.run(DialogOpenerNew.java:21)
at com.xtremelabs.robolectric.util.Scheduler.postDelayed(Scheduler.java:31)
at com.xtremelabs.robolectric.util.Scheduler.post(Scheduler.java:36)
at com.xtremelabs.robolectric.shadows.ShadowActivity.runOnUiThread(ShadowActivity.java:168)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.xtremelabs.robolectric.bytecode.ShadowWrangler.methodInvoked(ShadowWrangler.java:87)
at com.xtremelabs.robolectric.bytecode.RobolectricInternals.methodInvoked(RobolectricInternals.java:111)
at android.app.Activity.runOnUiThread(Activity.java)
at com.shinyandroid.gui.DialogOpenerNew.run(DialogOpenerNew.java:16)
at com.shinyandroid.view.ActionableSprite.touchesEnded(ActionableSprite.java:26)
at com.shinyandroid.TouchHandlers.touchesEnded(TouchHandlers.java:26)
at com.shinyandroid.BaseMenuLayer.ccTouchesEnded(BaseMenuLayer.java:101)
at com.shinyandroid.test.TestHelper.upInRect(TestHelper.java:163)
at com.shinyandroid.test.TestHelper.touchInRect(TestHelper.java:145)
at com.shinyandroid.StoreMenuHelper.doTouch(StoreMenuHelper.java:15)
at com.shinyandroid.StoreMenuHelper.touchSidewalksButton(StoreMenuHelper.java:10)
at com.shinyandroid.MainMenuLayerTest.selectingSidewalkTypeClosesAllMenus(MainMenuLayerTest.java:118)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
... 19 more
Caused by: java.lang.RuntimeException: java.lang.RuntimeException: no such directory ./res/xml
at com.xtremelabs.robolectric.res.ResourceLoader.init(ResourceLoader.java:99)
at com.xtremelabs.robolectric.res.ResourceLoader.inflateView(ResourceLoader.java:276)
at com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:43)
at com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:48)
at android.view.LayoutInflater.inflate(LayoutInflater.java)
at com.xtremelabs.robolectric.shadows.ShadowDialog.findViewById(ShadowDialog.java:134)
at android.app.Dialog.findViewById(Dialog.java)
at com.shinyandroid.gui.PurchasableItemsDialog.onCreate(PurchasableItemsDialog.java:33)
at com.xtremelabs.robolectric.shadows.ShadowDialog.show(ShadowDialog.java:100)
at android.app.Dialog.show(Dialog.java)
at com.shinyandroid.gui.DialogOpenerNew$1.run(DialogOpenerNew.java:21)
at com.xtremelabs.robolectric.util.Scheduler.postDelayed(Scheduler.java:31)
at com.xtremelabs.robolectric.util.Scheduler.post(Scheduler.java:36)
at com.xtremelabs.robolectric.shadows.ShadowActivity.runOnUiThread(ShadowActivity.java:168)
at android.app.Activity.runOnUiThread(Activity.java)
at com.shinyandroid.gui.DialogOpenerNew.run(DialogOpenerNew.java:16)
at com.shinyandroid.view.ActionableSprite.touchesEnded(ActionableSprite.java:26)
at com.shinyandroid.TouchHandlers.touchesEnded(TouchHandlers.java:26)
at com.shinyandroid.BaseMenuLayer.ccTouchesEnded(BaseMenuLayer.java:101)
at com.shinyandroid.test.TestHelper.upInRect(TestHelper.java:163)
at com.shinyandroid.test.TestHelper.touchInRect(TestHelper.java:145)
at com.shinyandroid.StoreMenuHelper.doTouch(StoreMenuHelper.java:15)
at com.shinyandroid.StoreMenuHelper.touchSidewalksButton(StoreMenuHelper.java:10)
at com.shinyandroid.MainMenuLayerTest.selectingSidewalkTypeClosesAllMenus(MainMenuLayerTest.java:118)
... 19 more
Caused by: java.lang.RuntimeException: no such directory ./res/xml
at com.xtremelabs.robolectric.res.DocumentLoader.loadResourceXmlDir(DocumentLoader.java:48)
at com.xtremelabs.robolectric.res.DocumentLoader.loadResourceXmlDir(DocumentLoader.java:39)
at com.xtremelabs.robolectric.res.ResourceLoader.loadPreferenceResources(ResourceLoader.java:131)
at com.xtremelabs.robolectric.res.ResourceLoader.init(ResourceLoader.java:92)
at com.xtremelabs.robolectric.res.ResourceLoader.inflateView(ResourceLoader.java:276)
at com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:43)
at com.xtremelabs.robolectric.shadows.ShadowLayoutInflater.inflate(ShadowLayoutInflater.java:48)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.xtremelabs.robolectric.bytecode.ShadowWrangler.methodInvoked(ShadowWrangler.java:87)
at com.xtremelabs.robolectric.bytecode.RobolectricInternals.methodInvoked(RobolectricInternals.java:111)
at android.view.LayoutInflater.inflate(LayoutInflater.java)
at com.xtremelabs.robolectric.shadows.ShadowDialog.findViewById(ShadowDialog.java:134)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.xtremelabs.robolectric.bytecode.ShadowWrangler.methodInvoked(ShadowWrangler.java:87)
at com.xtremelabs.robolectric.bytecode.RobolectricInternals.methodInvoked(RobolectricInternals.java:111)
at android.app.Dialog.findViewById(Dialog.java)
at com.shinyandroid.gui.PurchasableItemsDialog.onCreate(PurchasableItemsDialog.java:33)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.xtremelabs.robolectric.shadows.ShadowDialog.show(ShadowDialog.java:100)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.xtremelabs.robolectric.bytecode.ShadowWrangler.methodInvoked(ShadowWrangler.java:87)
at com.xtremelabs.robolectric.bytecode.RobolectricInternals.methodInvoked(RobolectricInternals.java:111)
at android.app.Dialog.show(Dialog.java)
at com.shinyandroid.gui.DialogOpenerNew$1.run(DialogOpenerNew.java:21)
at com.xtremelabs.robolectric.util.Scheduler.postDelayed(Scheduler.java:31)
at com.xtremelabs.robolectric.util.Scheduler.post(Scheduler.java:36)
at com.xtremelabs.robolectric.shadows.ShadowActivity.runOnUiThread(ShadowActivity.java:168)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at com.xtremelabs.robolectric.bytecode.ShadowWrangler.methodInvoked(ShadowWrangler.java:87)
at com.xtremelabs.robolectric.bytecode.RobolectricInternals.methodInvoked(RobolectricInternals.java:111)
at android.app.Activity.runOnUiThread(Activity.java)
at com.shinyandroid.gui.DialogOpenerNew.run(DialogOpenerNew.java:16)
at com.shinyandroid.view.ActionableSprite.touchesEnded(ActionableSprite.java:26)
at com.shinyandroid.TouchHandlers.touchesEnded(TouchHandlers.java:26)
at com.shinyandroid.BaseMenuLayer.ccTouchesEnded(BaseMenuLayer.java:101)
at com.shinyandroid.test.TestHelper.upInRect(TestHelper.java:163)
at com.shinyandroid.test.TestHelper.touchInRect(TestHelper.java:145)
at com.shinyandroid.StoreMenuHelper.doTouch(StoreMenuHelper.java:15)
at com.shinyandroid.StoreMenuHelper.touchSidewalksButton(StoreMenuHelper.java:10)
at com.shinyandroid.MainMenuLayerTest.selectingSidewalkTypeClosesAllMenus(MainMenuLayerTest.java:118)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
... 19 more

Add getCurrentView to ShadowViewGroup

Are there any technical hurdles to adding support for getCurrentView() to ShadowViewGroup? I'd like to be able to test the current shown view in a ViewFlipper.

Support for Testprojects?

Is it possible to use Robolectric with extra Test Projects. Can't get it working with this.

Extra Test Project means that i created an external Test Project with this command:

android create test-project -m ../HelloAndroid -n HelloAndroidTest -p HelloAndroidTest

if i do this with robolectric i can't get any views from the main application.

TestAttributeSet returns wrong values for ImageView.ScaleType

This is probably a symptom of a bigger underlying issue, but in any case, given the following layout:

<ImageView android:scaleType="fitXY" />

Android's own AttributeSet.getAttributeValue will return the value "fitXY" not as-is, but by its constant integer representation, which is "1". Robolectric's TestAttributeSet however returns this unprocessed as "fitXY". This will break code which relies on Android's behavior of mapping these literals to their internal constants.

As I said, I'm not sure whether ScaleType is the only occurrence of this behavior, or whether it'll break on other attributes, too.

HttpEntityStub implementation

What do you think about implementing HttpEntityStub? It can even inherit/delegate to org.apache.http.entity.BasicHttpEnity. It'd be useful to test Spring Android code. Can you see any possible problems here?

Failing test

OrgJsonTest fails. I am building against 1.6

java.lang.RuntimeException: Stub!
at org.json.JSONObject.(JSONObject.java:8)
at com.xtremelabs.robolectric.OrgJsonTest.testHasImplementation(OrgJsonTest.java:13)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at com.xtremelabs.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:151)
at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

Providing different classloader for a specific test

I discussed a long time ago with Christian Williams how to avoid mocks for http requests here:
http://groups.google.com/group/robolectric/browse_thread/thread/c2bf22f2b538a583/4f2e4acf14530766

Today I tried to solve this in a cleaner way but I failed.

I first tried to "unload" apache classes from the classloader but I couldn't make it.

Perhaps something like this
http://tutorials.jenkov.com/java-reflection/dynamic-class-loading-reloading.html

could be done.

After failing trying that I created a whole new runner to use a different classloader.
This is the what I did:

public class ApacheTestRunner extends RobolectricTestRunner {

  private static MyClassLoader myClassLoader;

  public ApacheTestRunner(Class<?> testClass)
      throws InitializationError {
    super(testClass, isInstrumented() ? null : ShadowWrangler
        .getInstance(), new MyClassLoader(ShadowWrangler.getInstance()),
        new RobolectricConfig(
        resourceFile("TestAndroidManifest.xml"), resourceFile("res"),
        resourceFile("assets")));
  }

  public ApacheTestRunner(Class<?> testClass, DatabaseMap databaseMap)
      throws InitializationError {
    super(testClass, isInstrumented() ? null : ShadowWrangler
        .getInstance(),
        new MyClassLoader(ShadowWrangler.getInstance()),
        new RobolectricConfig(
        resourceFile("TestAndroidManifest.xml"), resourceFile("res"),
        resourceFile("assets")), databaseMap);
  }
}

but when I run it, I get:

Caused by: java.lang.LinkageError: loader constraint violation: loader (instance of com/xtremelabs/robolectric/tester/org/apache/http/MyClassLoader) previously initiated loading for a different type with name "javassist/ClassPool"

How can I solve this?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.