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.