Spying or Mocking Abstract Classes (窥探或模拟抽象类)

17 Mar 2025 | 4 分钟阅读

Abstract classes are referred to as the class declared with the abstract keyword that may or may not include the abstract methods. In Java, abstract classes cannot be instantiated, but they can be sub-classed. It can also have static fields and static methods.

In this section, we will discuss mocking or spying of abstract classes. We will analyze several cases of testing the abstract classes using non-abstract methods.

For spying or mocking the abstract classes, we need to add the following Maven dependencies (为了窥探或模拟抽象类,我们需要添加以下 Maven 依赖项)

  • JUnit
  • Mockito
  • PowerMock

All the required dependencies of the project are given below (下面给出了该项目的所有必需依赖项)

The PowerMock dependencies are only required for the test in which we make use of PowerMock.(PowerMock 依赖项仅在测试中使用 PowerMock 时才需要)

Examples of Mocking Abstract Class (模拟抽象类的例子)

1. Spying abstract class using Mockito.spy() (使用 Mockito.spy() 窥探抽象类)

In this example, we are going to spy the abstract classes using the Mockito.spy() method. The Mockito.spy() method is used to create a spy instance of the abstract class.

Step 1: Create an abstract class named Abstract1_class that contains both abstract and non-abstract methods.(第 1 步:创建一个名为 Abstract1_class 的抽象类,该类包含抽象方法和非抽象方法)

Abstract1_class.java

Step 2: Create a JUnit test case named Abstract1Test. It contains a spy instance of the abstract class. (第 2 步:创建一个名为 Abstract1Test 的 JUnit 测试用例。它包含抽象类的 spy 实例)

Abstract1Test.java

输出

The following output shows that the test is successfully running.(以下输出显示测试正在成功运行)

Spying or Mocking Abstract Classes

The drawback of using the Mockito.spy() method is that it will invoke the abstract class constructor during the creation of spy instance. In most of the cases, the constructor uses external dependencies that can be an obstacle to our unit test executions. These external dependencies are usually known as the test impediments. It is the reason to use Mockito.mock() method for mocking abstract classes.(使用 Mockito.spy() 方法的缺点是它会在创建 spy 实例时调用抽象类构造函数。在大多数情况下,构造函数使用外部依赖项,这可能会成为我们单元测试执行的障碍。这些外部依赖项通常被称为**测试障碍**。这就是使用 Mockito.mock() 方法模拟抽象类的原因)

2. Mocking abstract class using Mockito.mock() (使用 Mockito.mock() 模拟抽象类)

In this example, we are going to mock the abstract classes using the Mockito.mock() method.

Usually, mocking is used to create a clone or dummy object of the class. In other words, it makes a class vacant from its logic or algorithms. The created mock instance does not contain code (logic) inside the methods.

Step 1: Create an abstract class named Abstract_Class that contains both abstract and non- abstract methods.(第 1 步:创建一个名为 Abstract_Class 的抽象类,该类包含抽象方法和非抽象方法)

Abstract_Class.java

Step 2: Create a JUnit test case named AbstractTestClass for mocking the abstract class.(第 2 步:创建一个名为 AbstractTestClass 的 JUnit 测试用例,用于模拟抽象类)

AbstractTestClass.java

In the above code, ac is a mocked instance created using Mockito.mock() method.(在上面的代码中,ac 是使用 Mockito.mock() 方法创建的模拟实例)

输出

The following output shows that the test is successfully running using Mockito.(以下输出显示测试正在使用 Mockito 成功运行)

Spying or Mocking Abstract Classes

The above approach is not the best, but it can be used. The next approach is recommended because it uses PowerMock, and can have control over the private methods defined in the abstract classes.(上述方法不是最佳方法,但可以使用。推荐使用下一个方法,因为它使用 PowerMock,并且可以控制在抽象类中定义的私有方法)

3. Mocking abstract class using PowerMock (使用 PowerMock 模拟抽象类)

In the following example, we will use PowerMockito.mock() method for mocking the abstract classes. Using PowerMock instead of Mockito.mock() is a better approach as it can have control over the private as well as static methods.(在下面的示例中,我们将使用 PowerMockito.mock() 方法来模拟抽象类。使用 PowerMock 代替 Mockito.mock() 是一个更好的方法,因为它可以控制私有方法和静态方法)

Step1: Create an abstract class named Abstract_class that contains both abstract and non-abstract methods.(第 1 步:创建一个名为 Abstract_class 的抽象类,该类包含抽象方法和非抽象方法)

Abstract_class.java

Step 2: Create a JUnit test case named AbstractTestClass for testing purposes.(第 2 步:创建一个名为 AbstractTestClass 的 JUnit 测试用例,用于测试)

AbstractTestClass.java

Here, we have asked the PowerMock to stub the private method's return values so that we can test the sayMock() method without any test impediments. Mockito alone cannot stub this method, that is why we have used PowerMock along with Mockito.(在这里,我们要求 PowerMock 存根私有方法的返回值,以便我们可以在没有任何测试障碍的情况下测试 sayMock() 方法。仅靠 Mockito 无法存根此方法,这就是我们结合使用 PowerMock 和 Mockito 的原因)

输出

The following output shows that the test is successfully running using PowerMock with Mockito.(以下输出显示测试正在使用 PowerMock 和 Mockito 成功运行)

Spying or Mocking Abstract Classes
下一主题#