使用 testng、mockito 和 powermock 模拟系统 class 方法
Mocking System class method using testng, mockito and powermock
我目前正在为使用函数 System.getenv("some_environment_variable")
的遗留代码编写测试
当我尝试使用 mockito 和 powermock(在 testng 框架下使用)模拟这些变量时遇到问题
到目前为止我所做的是
@BeforeClass
public void setup() {
PowerMockito.mockStatic(System.class);
PowerMockito.when(System.getenv("hello")).thenReturn("world");
}
@Test
public void test() {
assertEquals(System.getenv("hello"), "world");
}
但是当我尝试 运行 上面的代码时,出现以下错误:
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
you stub either of: final/private/equals()/hashCode() methods.
Those methods cannot be stubbed/verified.
Mocking methods declared on non-public parent classes is not supported.
inside when() you don't call method on mock but on some other object.
所以我读到并看到在尝试通过模拟 class 本身来模拟方法时引发了这个错误,但这里不是这种情况。
还有另一个 JUnit 库可以帮助您:system-rules,除其他外,它允许您设置和恢复环境变量。它与 JUnit @Rule
s
结合使用
在玩弄了一段时间之后,这是我设法做到的。
简而言之,为了让 powermockito 和 TestNG 相互协作,您必须执行以下操作(引用博客 post,其 link 在下面共享,以便答案是完整的,即使博客在以后的某个时间点不可用,也会很有用)
将 TestNG 配置为使用 PowerMock 对象工厂:您可以通过 <suite>
标记中的属性 object-factory
来执行此操作您的套件 xml 或通过 @org.testng.annotations.ObjectFactory
注释方法 returns powermock 对 TestNG 接口的实现 org.testng.IObjectFactory
即 org.powermock.modules.testng.PowerMockObjectFactory
(或)通过扩展 org.powermock.modules.testng.PowerMockTestCase
使用 @PrepareForTest
准备静态 class 以供 PowerMockito
模拟
详情请参考this博客。
这是一个工作示例:
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.testng.IObjectFactory;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.ObjectFactory;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
@PrepareForTest(System.class)
public class SampleTestClass {
@BeforeClass
public void setup() {
PowerMockito.mockStatic(System.class);
PowerMockito.when(System.getenv("hello")).thenReturn("world");
}
@Test
public void test() {
assertEquals(System.getenv("hello"), "world");
}
@ObjectFactory
public IObjectFactory getObjectFactory() {
return new org.powermock.modules.testng.PowerMockObjectFactory();
}
}
我使用以下依赖项来创建此示例
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-testng</artifactId>
<version>1.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.7.0</version>
<scope>test</scope>
</dependency>
我目前正在为使用函数 System.getenv("some_environment_variable")
当我尝试使用 mockito 和 powermock(在 testng 框架下使用)模拟这些变量时遇到问题
到目前为止我所做的是
@BeforeClass
public void setup() {
PowerMockito.mockStatic(System.class);
PowerMockito.when(System.getenv("hello")).thenReturn("world");
}
@Test
public void test() {
assertEquals(System.getenv("hello"), "world");
}
但是当我尝试 运行 上面的代码时,出现以下错误:
org.mockito.exceptions.misusing.MissingMethodInvocationException: when() requires an argument which has to be 'a method call on a mock'. For example: when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
you stub either of: final/private/equals()/hashCode() methods. Those methods cannot be stubbed/verified. Mocking methods declared on non-public parent classes is not supported.
inside when() you don't call method on mock but on some other object.
所以我读到并看到在尝试通过模拟 class 本身来模拟方法时引发了这个错误,但这里不是这种情况。
还有另一个 JUnit 库可以帮助您:system-rules,除其他外,它允许您设置和恢复环境变量。它与 JUnit @Rule
s
在玩弄了一段时间之后,这是我设法做到的。
简而言之,为了让 powermockito 和 TestNG 相互协作,您必须执行以下操作(引用博客 post,其 link 在下面共享,以便答案是完整的,即使博客在以后的某个时间点不可用,也会很有用)
将 TestNG 配置为使用 PowerMock 对象工厂:您可以通过
<suite>
标记中的属性object-factory
来执行此操作您的套件 xml 或通过@org.testng.annotations.ObjectFactory
注释方法 returns powermock 对 TestNG 接口的实现org.testng.IObjectFactory
即org.powermock.modules.testng.PowerMockObjectFactory
(或)通过扩展org.powermock.modules.testng.PowerMockTestCase
使用
@PrepareForTest
准备静态 class 以供 PowerMockito 模拟
详情请参考this博客。
这是一个工作示例:
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.testng.IObjectFactory;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.ObjectFactory;
import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;
@PrepareForTest(System.class)
public class SampleTestClass {
@BeforeClass
public void setup() {
PowerMockito.mockStatic(System.class);
PowerMockito.when(System.getenv("hello")).thenReturn("world");
}
@Test
public void test() {
assertEquals(System.getenv("hello"), "world");
}
@ObjectFactory
public IObjectFactory getObjectFactory() {
return new org.powermock.modules.testng.PowerMockObjectFactory();
}
}
我使用以下依赖项来创建此示例
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-testng</artifactId>
<version>1.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.7.0</version>
<scope>test</scope>
</dependency>