简体   繁体   中英

Mockito mock setter() and override getter()

I am not doing a unitTesting on Android Application.

TextChoiceAdapter.java:

public class TextChoiceAdapter extends ArrayAdapter<String> {
    public Context context;
    public int selectedPosition = -1;   //Otherwise Android set zero then choice A will be selected automatically
    public void choiceSelection(View rowView, int position){
        if (selectedPosition == position)
            rowView.setBackgroundColor(0xA0FF8000); // orange
        else
            rowView.setBackgroundColor(Color.TRANSPARENT);
    }
    public TextChoiceAdapter(Context context,int resources, List<String> textChoiceList) {
        super(context, resources, textChoiceList);
        this.context = context;
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent){
      ...
    }
}

TextChoiceAdapterTest.java:

public class TextChoiceAdapterTest{
    private TextChoiceAdapter textChoiceAdapter;
    private ArrayList<String> textChoiceList;
    @Before
    public void setUp(){
        textChoiceList = new ArrayList<>();
        textChoiceList.add("North");
        textChoiceList.add("East");
        textChoiceList.add("West");
        textChoiceList.add("South");
        Context context = mock(Context.class);
        textChoiceAdapter = new TextChoiceAdapter(context, 1, textChoiceList);
    }
    @Test
        public void testChoiceSelection(){
    //https://stackoverflow.com/questions/10217793/mockito-how-to-stub-getter-setter

    textChoiceAdapter.selectedPosition = 1;
    Context context = mock(Context.class);

    //Try my own object class.
    class mockRowView extends View{
        int backgroundColor;
        public mockRowView(Context context){
            super(context);
        }
        public void setBAckgroundColor(int a){
            this.backgroundColor = a;
        }
        public int getBackgroundColor(){
            return this.backgroundColor;
        }
    }
    View rowView = mock(mockRowView.class);
    textChoiceAdapter.choiceSelection(rowView, 1);
    assertEquals(rowView.getBackgroundColor(), 0xA0FF8000);
}
}

Error:
java.lang.AssertionError: Expected :null Actual :-1593868288

My question:
How to mock my rowView with setter() and getter() properly?
I want different answer from different input.

I am imitating Mockito: how to stub getter setter

Thank you for your attentions Ferrybig and Boris van Katwijk. I will follow your advice from now on.
1. Create MockRowView class
2. Mock that class.
3. For setter method use. doCallRealMethod()
4. Use direct access to variable. Since second time it called will return 0.

@Test
    public void testChoiceSelection(){

        textChoiceAdapter.selectedPosition = 1;
        Context context = mock(Context.class);

        //Try my own object class.
        class MockRowView extends View{
            int backgroundColor;
            public MockRowView(Context context){
                super(context);
            }
            @Override
            public void setBackgroundColor(int a){
                this.backgroundColor = a;
            }
            //User direct access will not cause a problem when do assertEquals()
        }

        MockRowView rowView = mock(MockRowView.class);
        doCallRealMethod().when(rowView).setBackgroundColor(anyInt());

        textChoiceAdapter.selectedPosition = 2;
        textChoiceAdapter.choiceSelection(rowView, 1);
        assertEquals(rowView.backgroundColor, Color.TRANSPARENT);
        textChoiceAdapter.choiceSelection(rowView, 2);
        assertEquals(rowView.backgroundColor, 0xA0FF8000);
    }

A small but important note is that the arguments in your assertEquals are swapped. The first argument should be what you expect, the second what you actually got.

The error message therefore actually indicated that you have successfully mocked your rowView object. When you invoked getBackgroundColor() , you got null , which is what a mocked object does.

You can specify behaviour for a method on a mocked object using Mockito's when mechanism:

Mockito.when(rowView.getBackgroundColor()).thenReturn(42);

However, I feel like you are actually depending on the natural functionality of the rowView object. You might want to not mock this object, but rather use a naturally created instance. You could mock dependencies of this object if needed. It does not make much sense to call a method of a mocked object in a test assertion.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM