之前的Spock系列mock静态方法主要是通过使用PowerMock实现的,但是使用JMock的同学也挺多的,所以这篇文章讲下在Spock中如何使用JMockit来mock静态方法。
比如下面的业务代码demo,记录日志的logger
对象是调用LoggerServiceFactory
工厂类的静态方法获取的,这时候就可以使用JMockit把他的静态方法getLoggerService
给mock掉,因为日志类一般初始化的时候会加载一些配置资源,跑单测的时候比较耗时间。
实例代码如下:
public class MyClass {
private LoggerService logger = LoggerServiceFactory.getLoggerService();
public int testStatic(int orderId) {
logger.info("testStatic request", orderId);
if (ConfigUtils.staticMethod()) {
// 业务逻辑...
return 1;
} else {
// 业务逻辑...
return 2;
}
}
}
单元测试代码:
class SpockWithJMockTest extends Specification {
def instance = new MyClass()
def logger = Mock(LoggerService)
void setupSpec() {
new MockUp<LoggerServiceFactory>() {
@Mock
static LoggerService getLoggerService() {
return null
}
}
}
void setup() {
instance.logger = logger
}
}
用法和在Junit里使用JMock一样,没什么区别。
主要是如果你想结合Spock的where表格方式实现jmock多次mock(动态mock)的话需要结合groovy闭包的用法,闭包的用法参考之前一篇文章:Spock单元测试高级语法-Groovy闭包
比如还是上面这个MyClass
业务类的testStatic
方法内部会调用一个工具类的静态方法ConfigUtils.staticMethod()
,然后根据他的返回值走不同的逻辑,
可以使用jmock+where每次mock不同的值返回,以覆盖不同的分支逻辑,完整代码如下:
import mockit.Mock
import mockit.MockUp
import mockit.internal.state.SavePoint
import spock.lang.Specification
import spock.lang.Unroll
/**
*
* @Author: java老k
* @Date: Created in 2021/5/28 11:07
* @Modified By:
*/
class SpockWithJMockTest extends Specification {
def instance = new MyClass()
def logger = Mock(LoggerService)
void setupSpec() {
new MockUp<LoggerServiceFactory>() {
@Mock
static LoggerService getLoggerService() {
return null
}
}
}
void setup() {
instance.logger = logger
}
def savePoint = new SavePoint()
def cleanup() {
savePoint.rollback() // 如果是多次使用jmock,需要每次执行完一次用例后清除下保存点,否则上一次的jmock值会影响后续的jmock
}
@Unroll
def "测试JMock静态方法"() {
given:
mockClosure()
when:
def response = instance.testStatic(1)
then:
response == result
where: "使用JMock动态mock"
mockClosure | result
mockStatic(true) | 1
mockStatic(false) | 2
}
def mockStatic(bool) {
// 这里返回的是闭包
return {new MockUp<ConfigUtils>() {
@Mock
boolean staticMethod(){
return bool
}
}}
}
}
注:普通的实例方法建议还是使用Spock自带的mock来模拟(比如使用Spring @Autowired注入的实例,理论上都可以使用Spock自带的mock)
除特别注明外,本站所有文章均为老K的Java博客原创,转载请注明出处来自https://javakk.com/2062.html
暂无评论