gpt4 book ai didi

unit-testing - PowerMockito 在模拟私有(private)方法以测试公共(public)方法时返回 null

转载 作者:行者123 更新时间:2023-12-04 12:53:32 25 4
gpt4 key购买 nike

我正在尝试编写一个比较字符串相等性的测试。

这是应该测试的类的代码片段

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");
}
}

如您所见,我想测试公共(public)方法concatenate,它调用同一个类中的私有(private)方法concatenateTwoString。我的想法是,我想为私有(private)方法制作一个模拟对象,无论何时从公共(public)方法调用它,它都应该返回常量值 "someText"

但它从私有(private)方法 concatenateTwoString 返回 null 而不是 "someText"

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

有人知道如何解决吗?

依赖版本:

  1. junit-jupiter - 5.7.2
  2. junit-platform-launcher - 1.8.1
  3. 模拟核心 - 3.12.4
  4. mockito-junit-jupiter - 3.12.4
  5. powermock-核心 - 2.0.9
  6. powermock-api-mockito2 - 2.0.9

最佳答案

作为@heaprc在他的帖子中提到,“测试”方法可以正确执行,在我们使用JUnit4的情况下而不是 JUnit5并通过添加 JUnit4 powerMock 注释 @RunWith(PowerMockRunner.class) .

一切都是正确的,在JUnit5的情况下,没有直接的解决方案来模拟公共(public)方法下的私有(private)方法。

那么我们有什么选择呢?

在这种情况下,在 m.o 中有三个选项:

  1. 离开JUnit5对于 "Test framework"并且不要试图模拟私有(private)方法。首先,想想你是否真的想测试那个 private方法,如果有必要测试它 package-private (把方法改成package-private就打破了封装的概念,但是如果真的需要测试的话,我觉得问题不大)
  2. 降级你的"Test framework"来自 JUnit5JUnit4 .但在这种情况下,如果您已经在 JUnit5 中编写了 100 个测试您将必须更改所有这些才能在 JUnit4 上工作.事实上,你必须降级你的框架真的很烦人,而且你必须为 JUnit4 重写 100 个测试。非常刺激。
  3. 制作JUnit4JUnit5一起工作。我认为这是更好的解决方案,示例如下:

您的 pom.xml 中必须有以下依赖项文件。

pom.xml

 <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>
  • junit-vintage-engine允许你运行 JUnit4测试。
  • junit-jupiter-engine允许你运行 JUnit5测试。

代码片段

    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");
}
}

在这种情况下,您将运行 checkIfConcatenationWorksWithJunit4测试方法与 Junit4平台,和@RunWith(PowerMockRunner.class)将为这次执行工作。在 checkIfConcatenationWorksWithJunit5 的情况下方法,它将运行在 Junit5(Jupiter) 平台上。

最后

你必须添加maven-surefire-pluginpom.xml两个文件 JUnit4JUnit5在构建它或使用 maven commands 进行测试时进行测试.

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

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

关于unit-testing - PowerMockito 在模拟私有(private)方法以测试公共(public)方法时返回 null,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69316249/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com