如何在 junit 中模拟静态引用?
How to mock static reference in junit?
我在模拟项目中的静态成员时遇到问题。
请在下面找到与我的项目代码类似的示例。
class A {
private String place = null;
public methodA() {
this.place = LoadPlaceDao.placeDao.PlaceMap();
.........
.........
.........
}
}
public class LoadPlaceDao {
public static PlaceDao placeDao;
public LoadPlaceDao() {
placeDao = new PlaceDaoImpl();
}
}
主要 objective 我的测试只是代码覆盖率,
我正在尝试模拟 LoadPlaceDao.placeDao.PlaceMap();
在 LoadPlaceDao.placeDao 附近获取 NullPointerException,因此剩余的行不会被覆盖。
PowerMockito 仅适用于静态方法。
**placeDao 是静态引用。
PowerMock 是一个 JUnit 扩展,它利用 EasyMock 和 Mockito 的可能性来模拟静态方法(以及更多)。
我们的测试单元是 class 计算器,它仅将两个整数的加法委托给仅提供静态方法的 MathUtil:
public class Calculator {
public int add(int a, int b) {
return MathUtil.addInteger(a, b);
}
}
public abstract class MathUtil {
public static final int addInteger(int a, int b) {
return a + b;
}
private MathUtil() {}
}
出于某些不明确的原因,我们想要模拟 MathUtil,因为在我们的测试场景中,加法应该产生与正常情况不同的结果(在现实生活中,我们可能会模拟 web 服务调用或数据库访问)。怎么可能t
his be achieved? Have a look at the following test:
@RunWith(PowerMockRunner.class)
@PrepareForTest( MathUtil.class )
public class CalculatorTest {
/** Unit under test. */
private Calculator calc;
@Before public void setUp() {
calc = new Calculator();
PowerMockito.mockStatic(MathUtil.class);
PowerMockito.when(MathUtil.addInteger(1, 1)).thenReturn(0);
PowerMockito.when(MathUtil.addInteger(2, 2)).thenReturn(1);
}
@Test public void shouldCalculateInAStrangeWay() {
assertEquals(0, calc.add(1, 1) );
assertEquals(1, calc.add(2, 2) );
}
}
首先,我们使用PowerMock框架提供的专用测试运行器。通过 @PrepareForTest( MathUtil.class ) 注释,我们的 class 模拟准备就绪。此注释采用所有 classes 的列表进行模拟。在我们的示例中,此列表包含单个项目 MathUtil.class.
在我们的设置方法中,我们调用 PowerMockito.mockStatic(...)。 (我们可以为方法 mockStatic 编写一个静态导入,但这样你可以更清楚地看到这些方法来自哪里。)
然后我们定义我们的模拟行为调用 PowerMockito.when(...)。在我们的测试中,我们有通常的断言。
我在模拟项目中的静态成员时遇到问题。 请在下面找到与我的项目代码类似的示例。
class A {
private String place = null;
public methodA() {
this.place = LoadPlaceDao.placeDao.PlaceMap();
.........
.........
.........
}
}
public class LoadPlaceDao {
public static PlaceDao placeDao;
public LoadPlaceDao() {
placeDao = new PlaceDaoImpl();
}
}
主要 objective 我的测试只是代码覆盖率, 我正在尝试模拟 LoadPlaceDao.placeDao.PlaceMap(); 在 LoadPlaceDao.placeDao 附近获取 NullPointerException,因此剩余的行不会被覆盖。 PowerMockito 仅适用于静态方法。 **placeDao 是静态引用。
PowerMock 是一个 JUnit 扩展,它利用 EasyMock 和 Mockito 的可能性来模拟静态方法(以及更多)。
我们的测试单元是 class 计算器,它仅将两个整数的加法委托给仅提供静态方法的 MathUtil:
public class Calculator {
public int add(int a, int b) {
return MathUtil.addInteger(a, b);
}
}
public abstract class MathUtil {
public static final int addInteger(int a, int b) {
return a + b;
}
private MathUtil() {}
}
出于某些不明确的原因,我们想要模拟 MathUtil,因为在我们的测试场景中,加法应该产生与正常情况不同的结果(在现实生活中,我们可能会模拟 web 服务调用或数据库访问)。怎么可能t
his be achieved? Have a look at the following test:
@RunWith(PowerMockRunner.class)
@PrepareForTest( MathUtil.class )
public class CalculatorTest {
/** Unit under test. */
private Calculator calc;
@Before public void setUp() {
calc = new Calculator();
PowerMockito.mockStatic(MathUtil.class);
PowerMockito.when(MathUtil.addInteger(1, 1)).thenReturn(0);
PowerMockito.when(MathUtil.addInteger(2, 2)).thenReturn(1);
}
@Test public void shouldCalculateInAStrangeWay() {
assertEquals(0, calc.add(1, 1) );
assertEquals(1, calc.add(2, 2) );
}
}
首先,我们使用PowerMock框架提供的专用测试运行器。通过 @PrepareForTest( MathUtil.class ) 注释,我们的 class 模拟准备就绪。此注释采用所有 classes 的列表进行模拟。在我们的示例中,此列表包含单个项目 MathUtil.class.
在我们的设置方法中,我们调用 PowerMockito.mockStatic(...)。 (我们可以为方法 mockStatic 编写一个静态导入,但这样你可以更清楚地看到这些方法来自哪里。)
然后我们定义我们的模拟行为调用 PowerMockito.when(...)。在我们的测试中,我们有通常的断言。