当前位置: 首页 > 知识库问答 >
问题:

使用Robolectric和PowerMock生成零%代码覆盖率的领域单元测试

游皓
2023-03-14

我遵循了这里的说明:

    null
@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.

共有1个答案

林正平
2023-03-14

我猜你是在利用Jacoco来收集报道。PowerMock与Jacoco/Eclemma之间存在一个已知的问题。我们将在下一个版本中修复它。

更新:PowerMock 1.6.6已经发布。它包括JaCoCo脱机检测代码的修复。因此,现在您可以通过使用JaCoCo maven插件和离线检测获得代码覆盖率

 类似资料:
  • 使用 Robolectric 和 Android 生成代码覆盖率(测试)报告 原文链接 : Code coverage reports using Robolectric and Android 原文作者 : Kris Vandermast 译文出自 : 开发技术前线 www.devtf.cn 译者 : normalme 校对者: Mr.Simple 状态 : 校对中 我写过许多测试驱动开发与陷阱

  • 是否有人能够从Maven Build获得JaCoCo中JMockit和Powermock单元测试的复盖范围? 我有一个Powermock单元测试的现有测试集,我希望逐步将其迁移到JMockit。但是我需要能够在一个报告中看到所有单元测试的测试覆盖范围,最好是在Sonar中。 通过将JaCoCo置于“脱机”模式,我确实使JMockit和Powermock测试与Surefire/JaCoCo一起运行(

  • 新的一年 之前因为上家公司的经营出了问题,年前的大裁员,过了一个漫长的春节。 之后加入了新公司,然后正好赶上一个很紧急的项目,忙成狗,因此好久没更新文章了。 不过,我又回来啦! 前言 自动化测试,我们将使用karma和nightmare,内容会包括: 单元测试 e2e测试(放下一篇文章) 其实,单元测试一般用在写公共包的时候,比如通用的js函数库,通用的UI组件库。基本不太会在做业务项目的时候还使

  • 我正在将ANT构建转换为Maven。我不用声纳。 在Maven中,Jacoco似乎并没有报告单元测试本身的覆盖率,而ANT报告。我也一直在尝试为我的Maven build获得这个,但是我没有找到任何东西。 似乎我应该添加一个

  • 问题内容: 试图使用Jacoco在Android的Robolectric测试中获得代码覆盖率,但在创建报告时,它只是拒绝承认我的Robolectric测试。 我的jacoco.gradle文件如下: 通过此设置,我可以获得“覆盖率”报告,但是尽管在“ src / test / java”中进行了Robolectric测试,但覆盖率为0%。 如果我在该文件中添加以下代码: 当Gradle尝试同步时,

  • 当我的单元测试通过Emma被“覆盖”时,我试图让Sonar IT代码覆盖为我工作。 我的情况: (1)我有大量使用JMockit的单元测试。删除JMockit不是一个选项。我想获得这些测试的单元测试覆盖报告。 (2)我进行了集成测试,简单地用不同的输入场景运行应用程序的核心服务器端部分(这是一个Spring web应用程序)。我想要它的代码覆盖报告。 对于第(1)部分,我选择使用Emma进行单元测