Я следовал инструкциям:Realm с Robolectric и PowerMock генерации покрытия кода нулевой%
- https://github.com/robolectric/robolectric/wiki/Using-PowerMock
- https://github.com/realm/realm-java/tree/master/examples/unitTestExample
настроить свои тесты Realm единицы. Все тесты проходят, но когда я пытаюсь создать покрытие кода, чтобы нажать на SonarQube, отчет о покрытии показывает 0% покрытия. Когда я выполняю стандартное покрытие кода Android Studio (как описано в ответе здесь: How to get code coverage using Android Studio?), он генерирует отчет, который показывает охват 91%. Однако проблема с этим подходом заключается в том, что это html-отчет, и нет возможности дать ему отчет xml, который можно использовать для SonarQube.
Это код тестового класса
@RunWith(RobolectricTestRunner.class)
@PowerMockIgnore({"org.mockito.*", "org.robolectric.*", "android.*"})
@PrepareForTest({Realm.class, RealmConfiguration.class, RealmCore.class, RealmLog.class})
@SuppressStaticInitializationFor("io.realm.internal.Util")
@Config(constants = BuildConfig.class, manifest = "src/main/AndroidManifest.xml", sdk = 21)
public class DecisionTreeTest
{
@Captor
ArgumentCaptor<Realm.Transaction.Callback> realmCallbackCaptor;
// Robolectric, Using Power Mock https://github.com/robolectric/robolectric/wiki/Using-PowerMock
@Rule
public PowerMockRule rule = new PowerMockRule();
private Context mockContext;
private final byte[] fakeRealmKey = {
-122, -115, -113, -111, -105, -104, -101, -99, -94, -93, -90, -87,
-77, -74, -67, -66, -63, -61, -56, -53, -48, -47, -33, -31,
-30, -28, -22, -17, -5, -3, -1, 3, 8, 11, 17, 18,
21, 22, 27, 30, 40, 42, 51, 52, 53, 54, 57, 59,
61, 63, 67, 70, 74, 76, 78, 85, 90, 91, 103, 108,
113, 117, 119, 127
};
@Before
public void setUp() throws Exception
{
// Setup Realm to be mocked. The order of these matters
mockStatic(RealmCore.class);
mockStatic(RealmLog.class);
mockStatic(Realm.class);
mockStatic(RealmConfiguration.class);
this.mockContext = RuntimeEnvironment.application;
Whitebox.setInternalState(
Realm.class,
"applicationContext",
RuntimeEnvironment.application);
/*
Better solution would be just mock the RealmConfiguration.Builder class.
But it seems there is some problems for powermock to mock it (static inner class).
We just mock the RealmCore.loadLibrary(Context) which will be called by
RealmConfiguration.Builder's constructor.
*/
doNothing().when(RealmCore.class);
RealmCore.loadLibrary(any(Context.class));
}
@Test(expected = DecisionTreeException.class)
public void persistSurvey_DecisionTreeRealmNotEnabled_ThrowsException() throws Exception
{
DecisionTree decisionTree = createSimpleDecisionTree();
Survey survey = decisionTree.getSurveyFromResource(R.raw.survey);
decisionTree.persistSurvey(survey, null, null);
}
@Test(expected = DecisionTreeException.class)
public void persistSurvey_NullAsFirstParam_ThrowsException() throws Exception
{
DecisionTree decisionTree = createRealmDecisionTree();
decisionTree.persistSurvey(null, null, null);
}
@Test
public void persistSurvey_SurveyAsFirstParam_ThrowsException() throws Exception
{
final Realm mockRealm = mock(Realm.class);
when(Realm.getInstance(any(RealmConfiguration.class))).thenReturn(mockRealm);
org.mockito.stubbing.Answer<Void> executeAnswer = new org.mockito.stubbing.Answer<Void>()
{
@Override
public Void answer(InvocationOnMock invocation) throws Throwable
{
((Realm.Transaction) invocation.getArguments()[0]).execute(mockRealm);
return null;
}
};
doAnswer(executeAnswer)
.when(mockRealm)
.executeTransactionAsync(
any(Realm.Transaction.class),
any(Realm.Transaction.OnSuccess.class),
any(Realm.Transaction.OnError.class));
DecisionTree decisionTree = createRealmDecisionTree();
Survey survey = decisionTree.getSurveyFromResource(R.raw.survey);
decisionTree.persistSurvey(survey, null, null);
verify(mockRealm).executeTransactionAsync(
any(Realm.Transaction.class),
any(Realm.Transaction.OnSuccess.class),
any(Realm.Transaction.OnError.class));
verify(mockRealm).copyToRealmOrUpdate(any(Survey.class));
}
private DecisionTree createRealmDecisionTree()
{
return new DecisionTree.Builder()
.setContext(mockContext)
.setRealmKey(fakeRealmKey)
.setRealmEnabled(true)
.build();
}
private DecisionTree createSimpleDecisionTree()
{
return new DecisionTree.Builder()
.setContext(RuntimeEnvironment.application)
.build();
}
}
Я думаю, что проблема заключается в следующей строке:
@Rule
public PowerMockRule rule = new PowerMockRule();
Однако, если удалить эту строку я получаю следующую ошибку хотя Строка @PrepareForTest не изменилась .:
org.powermock.api.mockito.ClassNotPreparedException:
The class io.realm.internal.RealmCore not prepared for test.
To prepare this class, add class to the '@PrepareForTest' annotation.
In case if you don't use this annotation, add the annotation on class or method level.
Одна из причин, по которой я полностью отказался от Powermock, заключается в том, что: иногда что-то просто не работает. И вы потратили ** часы ** на изучение; чаще всего не найдя для этого никакого решения. – GhostCat
Можете ли вы поделиться своим источником? –