Robolectric:在layout.xml中添加按钮时出错布局错误

时间:2013-02-13 10:58:24

标签: android robolectric

我正在使用Robolectric 1.1版,如果活动中有按钮,则无法运行我的测试。

add_emoticon_activity.xml

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" 
    >
    <Button
        android:id="@+id/addEmoticonButton"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/add_emoticon_button_text"
        />
</LinearLayout>

AddEmoticonActivity.java

import android.app.Activity;
import android.os.Bundle;

public class AddEmoticonActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.add_emoticon_activity);
    }
}

AddEmoticonActivityTest.java

import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import android.widget.Button;

import com.xtremelabs.robolectric.RobolectricTestRunner;
import com.xtremelabs.robolectric.shadows.ShadowHandler;
import com.xtremelabs.robolectric.shadows.ShadowToast;

@RunWith(RobolectricTestRunner.class)
public class AddEmoticonActivityTest {
    private AddEmoticonActivity addEmoticonActivity;
    private Button addButton;

    @Before
    public void setup() {
        addEmoticonActivity = new AddEmoticonActivity();
        addEmoticonActivity.onCreate(null);
        addButton = (Button) addEmoticonActivity.findViewById(R.id.addEmoticonButton);
    }

    @Test
    public void shouldDisplayErrorMessageWhenEmptyContentAdded() {
        addButton.performClick();

        ShadowHandler.idleMainLooper();
        assertThat(ShadowToast.getTextOfLatestToast(), equalTo(addEmoticonActivity.getResources().getString(R.string.no_content_error_message)));
    }
}

下面是我运行测试时得到的堆栈跟踪

java.lang.RuntimeException: error inflating layout/add_emoticon_activity
    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:377)
    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:101)
    at android.app.Activity.setContentView(Activity.java)
    at com.erlanggatjhie.emotextcon.activities.AddEmoticonActivity.onCreate(AddEmoticonActivity.java:10)
    at com.erlanggatjhie.emotextcon.activities.AddEmoticonActivityTest.setup(AddEmoticonActivityTest.java:24)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
    at com.xtremelabs.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:292)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    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(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.constructView(ViewLoader.java:228)
    at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.create(ViewLoader.java:179)
    at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:150)
    at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:153)
    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:377)
    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(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.xtremelabs.robolectric.bytecode.ShadowWrangler.methodInvoked(ShadowWrangler.java:99)
    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:101)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.xtremelabs.robolectric.bytecode.ShadowWrangler.methodInvoked(ShadowWrangler.java:99)
    at com.xtremelabs.robolectric.bytecode.RobolectricInternals.methodInvoked(RobolectricInternals.java:111)
    at android.app.Activity.setContentView(Activity.java)
    at com.erlanggatjhie.emotextcon.activities.AddEmoticonActivity.onCreate(AddEmoticonActivity.java:10)
    at com.erlanggatjhie.emotextcon.activities.AddEmoticonActivityTest.setup(AddEmoticonActivityTest.java:24)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    ... 20 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:382)
    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: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)
    at android.widget.Button.<init>(Button.java)
    at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.constructView(ViewLoader.java:228)
    at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.create(ViewLoader.java:179)
    at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:150)
    at com.xtremelabs.robolectric.res.ViewLoader$ViewNode.inflate(ViewLoader.java:153)
    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:377)
    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:101)
    at android.app.Activity.setContentView(Activity.java)
    at com.erlanggatjhie.emotextcon.activities.AddEmoticonActivity.onCreate(AddEmoticonActivity.java:10)
    at com.erlanggatjhie.emotextcon.activities.AddEmoticonActivityTest.setup(AddEmoticonActivityTest.java:24)
    ... 20 more

如果我从layout.xml中删除该按钮,它将会很好地工作。

有谁知道发生了什么?

非常感谢

1 个答案:

答案 0 :(得分:1)

看起来这一切都归结为导致原始问题的NullPointerException。

此提交发生在1.1发布后,它更改了ColorResourceLoader.java的第33行,这是您收到错误的行。

https://github.com/pivotal/robolectric/commit/f647512bd80162f9cb6b2fac8c7b0db984266967

如果您升级到更新版本的Robolectric,它可能会解决问题。我知道1.1是最新发布的版本,但有一个2.0 alpha 1版本已经发布。