2017-04-11 122 views
0

當我到了下面,當我在測試一個ListView與自定義對象和咖啡Android咖啡測試。檢測的ListView

I/TestRunner: java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0 
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255) 
at java.util.ArrayList.get(ArrayList.java:308) 
at android.widget.ArrayAdapter.getItem(ArrayAdapter.java:337) 
at android.widget.AdapterView.getItemAtPosition(AdapterView.java:997) 
at android.support.test.espresso.action.AdapterViewProtocols$StandardAdapterViewProtocol.getDataInAdapterView(AdapterViewProtocols.java:93) 
at android.support.test.espresso.action.AdapterDataLoaderAction.perform(AdapterDataLoaderAction.java:80) 
at android.support.test.espresso.ViewInteraction$1.run(ViewInteraction.java:144) 
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422) 
at java.util.concurrent.FutureTask.run(FutureTask.java:237) 
at android.os.Handler.handleCallback(Handler.java:739) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:145) 
at android.app.ActivityThread.main(ActivityThread.java:6873) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199) 

這裏例外獲取IndexOutOfBoundsException異常是我MainActivity.java

public class MainActivity extends AppCompatActivity { 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     final TextView textView = (TextView)findViewById(R.id.textView); 
     ListView listView = (ListView)findViewById(R.id.myListView); 

     ArrayList<Person> items = new ArrayList(); 
     for(int i=0; i<10; i++){ 
      items.add(new Person("name"+i, "desc"+i)); 
     } 
     ListViewAdapter adapter = new ListViewAdapter(this, R.layout.list_item, items); 
     listView.setAdapter(adapter); 

     AdapterView.OnItemClickListener mMessageClickedHandler = new AdapterView.OnItemClickListener() { 
      public void onItemClick(AdapterView parent, View v, int position, long id) { 
       textView.setText("" + position); 
      } 
     }; 
     listView.setOnItemClickListener(mMessageClickedHandler); 
    } 
} 

我的適配器類ListViewAdapter.java

public class ListViewAdapter extends ArrayAdapter<Person>{ 

    private final List<Person> _products; 
    private final int _layout; 

    public ListViewAdapter(@NonNull Context context, @LayoutRes int resource, List<Person> products) { 
     super(context, resource); 
     _layout = resource; 
     _products = products; 
    } 

    @Override 
    public View getView(int position, View convertview, ViewGroup parent) 
    { 
     View rowView = convertview; 
     if(convertview==null) { 
      LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      rowView = inflater.inflate(_layout, parent, false); 
     } 

     ((TextView)rowView.findViewById(R.id.productName)).setText(_products.get(position)._name); 
     ((TextView)rowView.findViewById(R.id.description)).setText(_products.get(position)._description); 

     return rowView; 
    } 

    @Override 
    public int getCount(){ 
     return _products.size(); 
    } 
} 

MainActivity的佈局文件

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" 
    tools:context="com.example.seanshi.testespresso2.MainActivity"> 

    <TextView 
     android:id="@+id/textView" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Hello World!"/> 

    <ListView 
     android:id="@+id/myListView" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" /> 
</LinearLayout> 

的適配器

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="horizontal" android:layout_width="match_parent" 
    android:layout_height="match_parent"> 
    <TextView 
     android:id="@+id/productName" 
     android:layout_width="100dp" 
     android:layout_height="50dp" /> 

    <TextView 
     android:id="@+id/description" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" /> 
</LinearLayout> 

佈局文件的應用也很好地工作

enter image description here

然後我說下面的測試類 「androidTest」 文件夾

package com.example.seanshi.testespresso2; 

import android.support.test.espresso.matcher.BoundedMatcher; 
import android.support.test.filters.SmallTest; 
import android.support.test.rule.ActivityTestRule; 
import android.support.test.runner.AndroidJUnit4; 

import org.hamcrest.Description; 
import org.hamcrest.Matcher; 
import org.junit.Rule; 
import org.junit.Test; 
import org.junit.runner.RunWith; 

import static android.support.test.espresso.Espresso.onData; 
import static android.support.test.espresso.Espresso.onView; 
import static android.support.test.espresso.action.ViewActions.click; 
import static android.support.test.espresso.assertion.ViewAssertions.matches; 
import static android.support.test.espresso.core.deps.guava.base.Preconditions.checkNotNull; 
import static android.support.test.espresso.matcher.ViewMatchers.withId; 
import static android.support.test.espresso.matcher.ViewMatchers.withText; 
import static org.hamcrest.Matchers.equalTo; 

@RunWith(AndroidJUnit4.class) 
@SmallTest 
public class ListViewTest { 
    @Rule 
    public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<MainActivity>(MainActivity.class); 

    @Test 
    public void testListView() 
    { 
     // withItemContent() is a customized matcher 
     onData(withItemContent("name1")).inAdapterView(withId(R.id.myListView)).perform(click()); 
     onView(withId(R.id.textView)).check(matches(withText("1"))); 
    } 

    public static Matcher<Object> withItemContent(final String expectedText) { 
     checkNotNull(expectedText); 
     return withItemContent(equalTo(expectedText)); 
    } 

    public static Matcher<Object> withItemContent(final Matcher<String> itemTextMatcher) { 
     checkNotNull(itemTextMatcher); 
     return new BoundedMatcher<Object, Person>(Person.class) { 
      @Override 
      public boolean matchesSafely(Person person) { 
       return itemTextMatcher.matches(person._name); 
      } 

      @Override 
      public void describeTo(Description description) { 
       description.appendText("with item content: "+itemTextMatcher.toString()); 
       itemTextMatcher.describeTo(description); 
      } 
     }; 
    } 
} 

我得到了java.lang.I ndexOutOfBoundsException當我運行這個espresso測試。

我檢查變量值在調試模式下,這裏是android.support.test.espresso.action.AdapterViewProtocols $ StandardAdapterViewProtocol.getDataInAdapterView()值

@Override 
public Iterable<AdaptedData> getDataInAdapterView(AdapterView<? extends Adapter> adapterView) { 
    List<AdaptedData> datas = Lists.newArrayList(); 
    for (int i = 0; i < adapterView.getCount(); i++) {  // getCount() return 10 
    int position = i; 
    Object dataAtPosition = adapterView.getItemAtPosition(position); // but getItemAtPosition(0) throws IndexOutOfBoundsException 
    datas.add(
     new AdaptedData.Builder() 
      .withDataFunction(new StandardDataFunction(dataAtPosition, position)) 
      .withOpaqueToken(position) 
      .build()); 
    } 
    return datas; 
} 

有誰知道爲什麼我得到了IndexOutOfBoundsException異常?

任何幫助表示讚賞。

+0

順便說說,這裏是Person類的內容。 public class Person { public String _name; public String _description; public Person(String name,String desc){ _name = name; _description = desc; } } –

回答

0

我找到了原因。這是因爲我在適配器中定義了一個新的List變量,並未在基類ArrayAdapter中的變量「List mObjects」上設置值。