mockito 静态方法Mockito模拟静态方法PowerMock

2022-07-20 10:05:34

mockito 静态方法

Mockito allows us to create mock objects. Since static method belongs to the class, there is no way in Mockito to mock static methods. However, we can use PowerMock along with Mockito framework to mock static methods.

Mockito允许我们创建模拟对象。 由于静态方法属于该类,因此Mockito中无法模拟静态方法。 但是,我们可以结合使用PowerMock和Mockito框架来模拟静态方法。

使用PowerMock的Mockito Mock静态方法(Mockito Mock Static Method using PowerMock)

PowerMock provides different modules to extendMockito framework and run JUnit and TestNG test cases.

PowerMock提供了不同的模块来扩展Mockito框架并运行JUnit和TestNG测试用例。

Note that PowerMock doesn’t supportJUnit 5 yet, so we will create JUnit 4 test cases. We will also learn how to integrateTestNG with Mockito and PowerMock.

请注意,PowerMock还不支持JUnit 5 ,因此我们将创建JUnit 4测试用例。 我们还将学习如何将TestNG与Mockito和PowerMock集成。

PowerMock依赖项(PowerMock Dependencies)

We need following PowerMock dependencies for mocking static methods in Mockito.

我们需要遵循PowerMock依赖关系才能在Mockito中模拟静态方法。

  • powermock-api-mockito2: This is the core PowerMock dependency and used to extend Mockito2 mocking framework. If you are using Mockito 1.x versions then usepowermock-api-mockito module.

    powermock-api-mockito2 :这是PowerMock的核心依赖项,用于扩展Mockito2模拟框架。 如果您使用的是Mockito 1.x版本,请使用powermock-api-mockito模块。
  • powermock-module-junit4: For running JUnit 4 test cases using PowerMock.

    powermock-module-junit4 :用于使用PowerMock运行JUnit 4测试用例。
  • powermock-module-testng: For running TestNG test cases and supporting PowerMock.

    powermock-module-testng :用于运行TestNG测试用例并支持PowerMock。

Below is the final pom.xml from our project.

以下是我们项目中的最终pom.xml。

<project xmlns="https://maven.apache.org/POM/4.0.0"
	xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="https://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.journaldev.powermock</groupId>
	<artifactId>PowerMock-Examples</artifactId>
	<version>0.0.1-SNAPSHOT</version>

	<properties>
		<testng.version>6.14.3</testng.version>
		<junit4.version>4.12</junit4.version>
		<mockito-core.version>2.19.0</mockito-core.version>
		<powermock.version>2.0.0-beta.5</powermock.version>
		<java.version>10</java.version>
	</properties>

	<dependencies>
		<!-- TestNG -->
		<dependency>
			<groupId>org.testng</groupId>
			<artifactId>testng</artifactId>
			<version>${testng.version}</version>
			<scope>test</scope>
		</dependency>
		<!-- JUnit 4 -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit4.version}</version>
			<scope>test</scope>
		</dependency>
		<!-- Mockito 2 -->
		<dependency>
			<groupId>org.mockito</groupId>
			<artifactId>mockito-core</artifactId>
			<version>${mockito-core.version}</version>
			<scope>test</scope>
		</dependency>
		<!-- PowerMock TestNG Module -->
		<dependency>
			<groupId>org.powermock</groupId>
			<artifactId>powermock-module-testng</artifactId>
			<version>${powermock.version}</version>
			<scope>test</scope>
		</dependency>
		<!-- PowerMock JUnit 4.4+ Module -->
		<dependency>
			<groupId>org.powermock</groupId>
			<artifactId>powermock-module-junit4</artifactId>
			<version>${powermock.version}</version>
			<scope>test</scope>
		</dependency>
		<!-- PowerMock Mockito2 API -->
		<dependency>
			<groupId>org.powermock</groupId>
			<artifactId>powermock-api-mockito2</artifactId>
			<version>${powermock.version}</version>
			<scope>test</scope>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.7.0</version>
				<configuration>
					<source>${java.version}</source>
					<target>${java.version}</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<version>2.22.0</version>
				<dependencies>
					<dependency>
						<groupId>org.apache.maven.surefire</groupId>
						<artifactId>surefire-junit47</artifactId>
						<version>2.22.0</version>
					</dependency>
					<dependency>
						<groupId>org.apache.maven.surefire</groupId>
						<artifactId>surefire-testng</artifactId>
						<version>2.22.0</version>
					</dependency>
				</dependencies>
				<configuration>
					<additionalClasspathElements>
						<additionalClasspathElement>src/test/java/</additionalClasspathElement>
					</additionalClasspathElements>
					<!-- TestNG Test Fails when executed from command line with message
						"Cannot use a threadCount parameter less than 1" 
						Works when threadCount is explicitly specified 
						https://gist.github.com/juherr/6eb3e93e2db33979b7e90b63ddadc888-->
					<threadCount>5</threadCount>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

Note that I am using2.0.0-beta.5 version of PowerMock. This version supports Java 10, however, it’s still in beta so there might be some issues present in complex cases.

请注意我正在使用2.0.0-beta.5版本的PowerMock。 该版本支持Java 10,但是它仍处于beta版本,因此在复杂情况下可能会出现一些问题。

When I tried to use current stable version1.7.x, I got the following errors.

当我尝试使用当前稳定的版本1.7.x ,出现以下错误。

java.lang.NoSuchMethodError: org.mockito.internal.handler.MockHandlerFactory.createMockHandler(Lorg/mockito/mock/MockCreationSettings;)Lorg/mockito/internal/InternalMockHandler;
	at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMethodInvocationControl(DefaultMockCreator.java:114)
	at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.createMock(DefaultMockCreator.java:69)
	at org.powermock.api.mockito.internal.mockcreation.DefaultMockCreator.mock(DefaultMockCreator.java:46)
	at org.powermock.api.mockito.PowerMockito.mockStatic(PowerMockito.java:73)

Here are GitHub issues opened for this exception –issue1 andissue2.

下面是打开了这个异常GitHub的问题-issue1issue2

Let’s create a simple class with a static method.

让我们用静态方法创建一个简单的类。

package com.journaldev.mockito.staticmethod;

public class Utils {

	public static boolean print(String msg) {
		System.out.println("Printing "+msg);
		return true;
	}
}

JUnit Mockito PowerMock示例(JUnit Mockito PowerMock Example)

We need to do the following to integrate PowerMock with Mockito and JUnit 4.

我们需要执行以下操作以将PowerMock与Mockito和JUnit 4集成。

  • Annotate test class with@RunWith(PowerMockRunner.class) annotation.

    使用@RunWith(PowerMockRunner.class)批注注释测试类。
  • Annotate test class with@PrepareForTest and provide classed to be mocked using PowerMock.

    使用@PrepareForTest注释测试类,并提供使用PowerMock@PrepareForTest分类。
  • UsePowerMockito.mockStatic() for mocking class with static methods.

    使用PowerMockito.mockStatic()通过静态方法模拟类。
  • UsePowerMockito.verifyStatic() for verifying mocked methods using Mockito.

    使用PowerMockito.verifyStatic()来验证使用Mockito的模拟方法。

Here is a complete example of mocking static method using Mockito and PowerMock in JUnit test case.

这是在JUnit测试案例中使用Mockito和PowerMock模拟静态方法的完整示例。

package com.journaldev.mockito.staticmethod;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.when;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(Utils.class)
public class JUnit4PowerMockitoStaticTest{

	@Test
	public void test_static_mock_methods() {
		PowerMockito.mockStatic(Utils.class);
		when(Utils.print("Hello")).thenReturn(true);
		when(Utils.print("Wrong Message")).thenReturn(false);
		
		assertTrue(Utils.print("Hello"));
		assertFalse(Utils.print("Wrong Message"));
		
		PowerMockito.verifyStatic(Utils.class, atLeast(2));
		Utils.print(anyString());
	}
}

TestNG Mockito PowerMock示例(TestNG Mockito PowerMock Example)

For TestNG test cases, we don’t need to use@RunWith annotation. We need test classes to extendPowerMockTestCase so thatPowerMockObjectFactory is used to create test class instance.

对于TestNG测试用例,我们不需要使用@RunWith批注。 我们需要测试类来扩展PowerMockTestCase以便使用PowerMockObjectFactory创建测试类实例。

package com.journaldev.mockito.staticmethod;

import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;

import static org.mockito.Mockito.*;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.testng.PowerMockTestCase;
import org.testng.annotations.Test;

@PrepareForTest(Utils.class)
public class TestNGPowerMockitoStaticTest extends PowerMockTestCase{

	@Test
	public void test_static_mock_methods() {
		PowerMockito.mockStatic(Utils.class);
		when(Utils.print("Hello")).thenReturn(true);
		when(Utils.print("Wrong Message")).thenReturn(false);
		
		assertTrue(Utils.print("Hello"));
		assertFalse(Utils.print("Wrong Message"));
		
		PowerMockito.verifyStatic(Utils.class);
		Utils.print("Hello");
		PowerMockito.verifyStatic(Utils.class, times(2));
		Utils.print(anyString());
	}
}

摘要(Summary)

PowerMock provides extended features for Mockito, one of them is the ability to test static methods. It’s easily integrated with JUnit 4 and TestNG. However, there is no near-term support plan for JUnit 5.

PowerMock为Mockito提供了扩展功能,其中之一就是能够测试静态方法。 它很容易与JUnit 4和TestNG集成。 但是,没有针对JUnit 5的近期支持计划。

GitHub Repository.GitHub Repository下载完整的项目。

翻译自:https://www.journaldev.com/21912/mockito-mock-static-method-powermock

mockito 静态方法

  • 作者:cunchi4221
  • 原文链接:https://blog.csdn.net/cunchi4221/article/details/107475398
    更新时间:2022-07-20 10:05:34