Как выполнить модульное тестирование пользовательского представления с атрибутом
У меня проблемы с созданием модульного теста для моего пользовательского представления. Я пытаюсь добавить атрибут и проверить его, если мой пользовательский класс представления понимает это правильно.
Вот как выглядит мой тест:
@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));
}
// ...
}
Который получает это исключение:
java.lang.ClassCastException: android.util.AttributeSet$MockitoMock$1142631110 cannot be cast to android.content.res.XmlBlock$Parser
Я попытался смоделировать TypeArray, как это делала эта статья, но мой взгляд рассматривает смоделированный контекст как нулевой.
Есть ли хороший способ создать контрольный пример для пользовательского представления?
1 ответ
Подумайте об использовании Robolectric, поскольку он устраняет необходимость в моковах.
AttributeSet as = Robolectric.buildAttributeSet().addAttribute(R.style.BaseRatingBar_srb_minRating, "2.5f").build()
BaseRatingBar brb = new BaseRatingBar(mContext, as);
У меня была такая же проблема, как и у вас. Как и вы, я хотел протестировать пользовательский вид. Вот как я это решил:
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());
}
}
И в моем классе CustomView:
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;
}
}
Попробуйте этот подход и опубликуйте точное сообщение об ошибке, если оно не работает. Надеюсь, поможет.