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

PowerMockito在模拟私有方法以测试公共方法时返回null

邢杰
2023-03-14

我试图编写一个测试来比较字符串的相等性。

下面是应该测试的类的代码片段

package ge.jibo.util;

public class TextManager {

  private String concatenateTwoString(String t1, String t2) {
    return t1 + t2;
  }

  public String concatenate(String t1, String t2) {
    return concatenateTwoString(t1, t2);
  }

}

这是一个测试类

package ge.jibo.util;

import org.junit.jupiter.api.Test;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;

import static org.assertj.core.api.Assertions.assertThat;

public class TextManagerTest {

  @Test
  @PrepareForTest(TextManager.class)
  void checkIfConcatenationWorks() throws Exception {
    TextManager textmanager = PowerMockito.spy(new TextManager());
    PowerMockito.doReturn("someText").when(textmanager,"concatenateTwoString", Mockito.anyString(), Mockito.anyString());
    String text = textmanager.concatenate("ji","bo");
    assertThat(text).isEqualTo("jibo");
  }
}

正如您所看到的,我想测试公共方法concatenate,它在同一个类中调用私有方法concatenatetWoString。这个想法是,我想为私有方法创建一个模拟对象,无论何时从公共方法调用它,它都应该返回常量值“sometext”

但是它返回null,而不是从私有方法ConcateNatetWoString返回“sometext”

org.opentest4j.AssertionFailedError: 
Expecting:
 <null>
to be equal to:
 <"jibo">
but was not.
Expected :jibo
Actual   :null
    null

共有1个答案

淳于思淼
2023-03-14

正如@heaprc在他的文章中提到的,当我们使用Junit4而不是Junit5并通过为powerMock@runwith(powerMockRunner.class)添加Junit4注释,“test”方法可以正确执行。

一切都是正确的,在JUnit5的情况下,没有直接的解决方案来模仿public方法下的private方法。

那么我们有什么选择呢?

    null
 <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter-engine</artifactId>
        <version>5.8.1</version>
    </dependency>
    <dependency>
        <groupId>org.junit.vintage</groupId>
        <artifactId>junit-vintage-engine</artifactId>
        <version>5.8.1</version>
    </dependency>


    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-module-junit4</artifactId>
        <version>2.0.9</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-api-mockito2</artifactId>
        <version>2.0.9</version>
        <scope>test</scope>
    </dependency>
    null
    import org.junit.Assert;
    import org.junit.jupiter.api.Assertions;
    import org.junit.jupiter.api.Test;
    import org.junit.runner.RunWith;
    import org.mockito.Mockito;
    import org.powermock.api.mockito.PowerMockito;
    import org.powermock.core.classloader.annotations.PrepareForTest;
    import org.powermock.modules.junit4.PowerMockRunner;
    
    @PrepareForTest(TextManager.class)
    @RunWith(PowerMockRunner.class)
    public class TextManagerTest {
    
        @org.junit.Test  //Test using Junit4
        public void checkIfConcatenationWorksWithJunit4() throws Exception {
            TextManager textmanager = PowerMockito.spy(new TextManager());
            PowerMockito.doReturn("jibo").when(textmanager, "concatenateTwoString", Mockito.anyString(), Mockito.anyString());
            String text = textmanager.concatenate("ji", "bo");
            Assert.assertEquals(text,"jibo");
        }
    
        @Test  //Test using Junit5
        public void checkIfConcatenationWorksWithJunit5() {
            Assertions.assertEquals("text","jibo");
        }
    }

在本例中,您将使用Junit4平台运行CheckifConcatenationWorksWithJunit4测试方法,并且@runwith(powermockrunner.class)将用于此执行。对于CheckifConcatenationWorksWithJunit5方法,它将在Junit5(Jupiter)平台上运行。

您必须在pom.xml文件中添加maven-surefire-plugin,以便在使用maven commands构建或测试junit4junit5时进行测试。

   <build>
        <plugins>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.22.2</version>
            </plugin>
        </plugins>
    </build>

如果不添加maven-surefire-plugin,运行时将执行唯一一个平台(JUnit4)测试。

 类似资料:
  • 有人能帮帮我吗?提前谢了。

  • 我试图模拟一个私有方法(executeGetRequest),在我声明要为私有方法返回的模拟的那一行中,私有方法实际上是用null参数执行的,因此抛出了一个NullPointerException。 VlcPlayerMinimal。爪哇: VlcPlayerMinimalTest。爪哇: 堆栈跟踪: 它似乎PowerMockito实际上是调用的方法,我试图在行PowerMockito.do返回(

  • 我试图在测试的类中模拟一个私有方法,如下所示。 现在我需要测试方法和mock。 我尝试创建间谍的上述类,但该方法得到调用时,我这样做下面 在第二行本身被调用。而且,不会被模仿。 也许我用错误的方式创建了间谍对象?无法执行

  • 我有一门课看起来像这样: 我想使用Mockito和Powermock为此编写一个单元测试。我知道我可以这样模仿私有方法: 但是我如何告诉它抛出异常呢?我知道会是这样的: 那里有什么? 请注意,异常是一个私有内部类,因此我不能只执行,因为从单元测试中无法访问。

  • 问题内容: 我当时正在上课,我想到了几个问题。 我注意到,其他类将使用的公共方法调用了一些私有方法来完成所有工作。现在,我知道OOD的原则之一就是尽可能多地私有化并隐藏所有实现细节。我不确定我是否完全理解其背后的逻辑。 我知道将字段设为私有很重要,以防止将无效值存储在字段中(这只是许多原因之一)。但是,对于私有方法,我不确定为什么它们如此重要。 例如,对于类,我们是否不能将所有实现代码都放入公共方