I'm having trouble to create a unit test for my custom view. I try to add an attribute and test it if my custom view class get it right.
Here's what my test looks like:
@RunWith(AndroidJUnit4.class)
@SmallTest
public class BaseRatingBarMinRatingTest {
private Context mContext;
@Before
public void setUp(){
mContext = InstrumentationRegistry.getTargetContext();
}
@Test
public void constructor_should_setMinRating_when_attriSetHasOne() throws Exception{
// 1. ARRANGE DATA
float minRating = 2.5f;
AttributeSet as = mock(AttributeSet.class);
when(as.getAttributeFloatValue(eq(R.styleable.BaseRatingBar_srb_minRating), anyFloat())).thenReturn(minRating);
// 2. ACT
BaseRatingBar brb = new BaseRatingBar(mContext, as);
// 3. ASSERT
assertThat(brb.getMinRating(), is(minRating));
}
// ...
}
Which gets this Exception:
java.lang.ClassCastException: android.util.AttributeSet$MockitoMock$1142631110 cannot be cast to android.content.res.XmlBlock$Parser
I tried mocking TypeArray like this article did, but my view treats the mocked context as null.
Is there any good way to create a test case for custom view?
FindParamAttribute: You use this attribute to describe how an element can be found on the page. You set this attribute on test methods or share it across all test methods of a particular test class by setting it on the test class that contains the test methods that will use the FindParam definitions.
Consider using Robolectric, as it eliminates the need for mocks.
AttributeSet as = Robolectric.buildAttributeSet().addAttribute(R.style.BaseRatingBar_srb_minRating, "2.5f").build()
BaseRatingBar brb = new BaseRatingBar(mContext, as);
I had a similar problem as you did. Like you, I wanted to test a custom View. This is how I solved it:
public class CustomViewTest {
@Mock
private Context context;
@Mock
private AttributeSet attributes;
@Mock
private TypedArray typedArray;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(context.obtainStyledAttributes(attributes, R.styleable.CustomView)).thenReturn(typedArray);
when(typedArray.getInteger(eq(R.styleable.CustomView_customAttribute), anyInt())).thenReturn(23);
}
@Test
public void constructor() {
CustomView customView = new CustomView(context, attributes);
assertEquals(23, customView.getCustomAttribute());
}
}
And in my CustomView class:
public CustomView(Context context, AttributeSet attrs) {
super(context, attrs);
if (attrs != null) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomView);
customAttribute = a.getInteger(R.styleable.CustomView_customAttribute, 19);
a.recycle();
} else {
customAttribute = 19;
}
}
Try this approach, and post the exact error message if it doesn't work. Hope it helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With