4

我有一个ListActivity它的适配器实现了 ViewHolder 模式。

适配器和视图:

private class PlaceAdapter extends ArrayAdapter<PlaceModel> {
    final int viewResourceId;

    public PlaceAdapter(Context context, int textViewResourceId, List<PlaceModel> objects) {
        super(context, textViewResourceId, objects);
        viewResourceId = textViewResourceId;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;

        if (convertView == null) {
            LayoutInflater inflater = getLayoutInflater();
            convertView = inflater.inflate(viewResourceId, null);

            holder = new ViewHolder(convertView);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        PlaceModel place = getItem(position);

        holder.name.setText(place.getName());
        holder.address.setText(place.getVicinity());

        return convertView;
    }
}

private class ViewHolder {
    public final ImageView image;
    public final TextView name;
    public final TextView address;

    public ViewHolder(View row) {
        image = (ImageView) row.findViewById(R.id.placeRow_imageView);
        name = (TextView) row.findViewById(R.id.placeRow_placeName);
        address = (TextView) row.findViewById(R.id.placeRow_placeAddress);
    }
}

当我在这门课上运行 Robolectric 测试时,我得到了NullPointerExceptionholder.name.setText线holder.address.setText

我的猜测是 Robolectric 不能row.findViewById正确处理。

我该如何解决?

这是一个例外:

java.lang.NullPointerException
at com.dgti.ds.activities.ChooseLocationActivity$PlaceAdapter.getView(ChooseLocationActivity.java:181)
at com.xtremelabs.robolectric.shadows.ShadowAdapterView.addViews(ShadowAdapterView.java:314)
at com.xtremelabs.robolectric.shadows.ShadowListView.addViews(ShadowListView.java:167)
at com.xtremelabs.robolectric.shadows.ShadowAdapterView.update(ShadowAdapterView.java:302)
at com.xtremelabs.robolectric.shadows.ShadowAdapterView.access$100(ShadowAdapterView.java:19)
at com.xtremelabs.robolectric.shadows.ShadowAdapterView$1.run(ShadowAdapterView.java:85)
at com.xtremelabs.robolectric.util.Scheduler.postDelayed(Scheduler.java:36)
at com.xtremelabs.robolectric.shadows.ShadowLooper.post(ShadowLooper.java:154)
at com.xtremelabs.robolectric.shadows.ShadowHandler.postDelayed(ShadowHandler.java:52)
at com.xtremelabs.robolectric.shadows.ShadowHandler.post(ShadowHandler.java:47)
at android.os.Handler.post(Handler.java)
at com.xtremelabs.robolectric.shadows.ShadowAdapterView.invalidateAndScheduleUpdate(ShadowAdapterView.java:81)
at com.xtremelabs.robolectric.shadows.ShadowAdapterView.setAdapter(ShadowAdapterView.java:45)
at com.xtremelabs.robolectric.shadows.ShadowListView.setAdapter(ShadowListView.java:83)
at android.widget.ListView.setAdapter(ListView.java)
at com.dgti.ds.activities.ChooseLocationActivity.onSuccess(ChooseLocationActivity.java:119)
at com.dgti.ds.activities.ChooseLocationActivityTests$1.answer(ChooseLocationActivityTests.java:105)
at com.dgti.ds.activities.ChooseLocationActivityTests$1.answer(ChooseLocationActivityTests.java:96)
at org.mockito.internal.stubbing.StubbedInvocationMatcher.answer(StubbedInvocationMatcher.java:34)
at org.mockito.internal.handler.MockHandlerImpl.handle(MockHandlerImpl.java:91)
at org.mockito.internal.handler.NullResultGuardian.handle(NullResultGuardian.java:29)
at org.mockito.internal.handler.InvocationNotifierHandler.handle(InvocationNotifierHandler.java:38)
at org.mockito.internal.creation.MethodInterceptorFilter.intercept(MethodInterceptorFilter.java:51)
at com.dgti.ds.service.DsServiceHelperImp$$EnhancerByMockitoWithCGLIB$$34fcae5f.placeSearch(<generated>)
at com.dgti.ds.service.DsServiceHelper.placeSearch(DsServiceHelper.java:278)
at com.dgti.ds.activities.ChooseLocationActivity.placeSearch(ChooseLocationActivity.java:153)
at com.dgti.ds.activities.ChooseLocationActivity.doSearch(ChooseLocationActivity.java:148)
at com.dgti.ds.activities.ChooseLocationActivity.onCreate(ChooseLocationActivity.java:52)
at com.dgti.ds.activities.ChooseLocationActivityTests.shouldAddPlacesToAdapterOnAPISuccessIfGoogleAPIKeyAlreadySet(ChooseLocationActivityTests.java:112)
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 org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at com.xtremelabs.robolectric.RobolectricTestRunner$1.evaluate(RobolectricTestRunner.java:288)
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.application.AppMain.main(AppMain.java:120)
4

1 回答 1

6

这就是我过去测试支架模式的方式。

// Test fields
CustomItem  item;
ListAdapter listAdapter;

@Before
public void setUp() throws Exception {
    listAdapter = new ListAdapter(new Activity());
    item = new CustomItem(whatever, is, important)
    listItemView = listAdapter.getView(item, null, null);
}

@Test
public void shouldRecycleViews() throws Exception {
    View recycleView = View.inflate(new Activity(), R.layout.custom_list_item, null);
    ListAdapter.ViewHolder viewHolder = createViewHolder(recycleView); // Static method in adapter
    recycleView.setTag(viewHolder);
    listItemView = listAdapter.getView(item, recycleView, null);
    assertSame(recycleView, listItemView);
}
于 2012-12-06T13:12:19.857 回答