Why is the protected end field null if the source code says an error during the Mockito test?

I created a test using Mockito 1.10.19 to test the RecyclerView adapter. (The code has been simplified to eliminate information noise, leaving the simplest version that still has a problem)

public class CustomAdapter extends RecyclerView.Adapter<CustomViewHolder> {

    private final Dependency dependency;

    public CustomAdapter(@NonNull Dependency dependency) {
        this.dependency = dependency;
    }

    public void refreshData() {
        dependency.refreshData();
        notifyDataSetChanged();
    }

    @Override
    public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.ingredients_item, parent, false);
        return new CustomViewHolder(view);
    }

    @Override
    public void onBindViewHolder(CustomViewHolder holder, int position) {
        dependency.bind(holder, position);
    }

    @Override
    public int getItemCount() {
        return dependency.getItemsCount();
    }
}

I introduced ridiculous dependencies into it, but the adapter would not be touched otherwise.

@RunWith(MockitoJUnitRunner.class)
public class CustomAdapterTest {

    private CustomAdapter adapter;
    @Mock
    private Dependecy dependencyMock;

    @Before
    public void setUp() throws Exception {
        adapter = new CustomAdapter(dependencyMock);
    }

    @Test
    public void testRefreshData() throws Exception {
        adapter.refreshData();
        verify(dependencyMock).refreshData();
        verifyNoMoreInteractions(dependencyMock);
    }
}

When the very simple test 'testRefreshData ()' is run, the adapter calls notifyDataSetChanged(). This causes a surge NullPointerException.

in android.support.v7.widget.RecyclerView $ AdapterDataObservable.notifyChanged (RecyclerView.java:10763) in android.support.v7.widget.RecyclerView $ Adapter.notifyDataSetChanged (RecyclerView.java:6342)

This happens in the code:

static class AdapterDataObservable extends Observable<AdapterDataObserver> {
    public boolean hasObservers() {
        return !mObservers.isEmpty();
    }
public void notifyChanged() {
    // since onChanged() is implemented by the app, it could do anything, including
    // removing itself from {@link mObservers} - and that could cause problems if
    // an iterator is used on the ArrayList {@link mObservers}.
    // to avoid such problems, just march thru the list in the reverse order.
    for (int i = mObservers.size() - 1; i >= 0; i--) {
        mObservers.get(i).onChanged();
    }
}

mObservers. , Observable<T> mObservers :

public abstract class Observable<T> {
    /**
     * The list of observers.  An observer can be in the list at most
     * once and will never be null.
     */
    protected final ArrayList<T> mObservers = new ArrayList<T>();

? - ? ? ( Robolectric, , )

- ; , .

: JUnit 4.12. Mockito 1.10.19, 25.0.0, Android Studio 2.2.2, jdk 1.8.0_112,

+4
1

, , , , Android JUnit.

, .

+4

Source: https://habr.com/ru/post/1659270/


All Articles