网站左下角广告代码,站酷网怎么赚钱,中国建设工程造价网,设计网站源码我们平时写单元测试时经常会遇到调用抽象类或父类的方法#xff0c;这些抽象方法可能是调用底层接口或数据库#xff0c;需要mock掉#xff0c;让抽象方法返回一个我们指定的值#xff0c;以便测试当前代码逻辑的场景。下面讲下Spock如何结合power mock实现动态mock抽象方法… 我们平时写单元测试时经常会遇到调用抽象类或父类的方法这些抽象方法可能是调用底层接口或数据库需要mock掉让抽象方法返回一个我们指定的值以便测试当前代码逻辑的场景。下面讲下Spock如何结合power mock实现动态mock抽象方法一. 抽象方法或父类方法动态mockAbstractService 是个抽象类我们需要把它的方法 parentMethod 模拟掉返回我们预先设置的期望值 代码示例public abstract class AbstractService {String parentMethod(){// 发起接口调用或数据库操作return parentMethod value; }}SubService是继承AbstractService 的子类在doSomething方法体里会调用抽象类的 parentMethod 方法逻辑然后根据抽象方法 parentMethod 的返回值走不同的逻辑public class SubService extends AbstractService { Autowired MoneyDAO moneyDAO;public String doSomething() { String parent super.parentMethod(); // 调用抽象类或父类方法if (parent1.equals(parent)) {// 执行parent1分支逻辑return sub1; }if (parent2.equals(parent)) {// 执行parent2分支逻辑return sub2; }if (parent3.equals(parent)) {// 执行parent3分支逻辑return sub3; }return other; }}如果要mock掉抽象类AbstractService 中的 parentMethod 方法, 并且每次mock的值不一样, 可以使用spock powermock来实现:单元测试代码如下/** * 测试抽象类方法或父类方法 * Author: www.javakk.com * Description: 公众号:Java老K * Date: Created in 14:53 2020/10/05 * Modified By: */RunWith(PowerMockRunner.class)PowerMockRunnerDelegate(Sputnik.class)PrepareForTest([SubService.class])class AbstractServiceTest extends Specification {Unroll def 测试抽象方法() { given: mock抽象类方法 def sub PowerMockito.mock(SubService) PowerMockito.when(sub.parentMethod()).thenReturn(parentValue) // mock掉抽象类的parentMethod, 返回动态mock值:mockParentReturn PowerMockito.when(sub.doSomething()).thenCallRealMethod() expect: 调用doSomething方法 sub.doSomething() result where: 验证分支场景 parentValue | resultparent1 | sub1parent2 | sub2parent3 | sub3parent4 | other }}使用power mock模拟掉抽象类的方法返回一个变量parentValue然后再放在Spock的where标签里即可实现动态mock的效果即每次调用返回的mock值都不一样parent1、parent2、parent3 ...二. 抽象方法实例方法的动态mock如果在SubService中还有引用其他实例对象的方法比如下面的业务代码public class SubService extends AbstractService { Autowired MoneyDAO moneyDAO; // 金额换算对象public String doSomethingAndDao() { String parent super.parentMethod(); // 调用抽象类或父类方法 BigDecimal money moneyDAO.getExchangeByCountry(parent); // 获取对应国家的金额if (parent1.equals(parent)) {return money CNY; }if (parent2.equals(parent)) {return money USD; }if (parent3.equals(parent)) {return money EUR; }return money.toString(); }}如果即要mock掉抽象类AbstractService 中的 parentMethod 方法又要mockmoneyDAO对象可以使用 Whitebox.setInternalState 方式单元测试代码如下/** * 测试抽象类方法或父类方法 * Author: www.javakk.com * Description: 公众号:Java老K * Date: Created in 14:53 2020/10/05 * Modified By: */RunWith(PowerMockRunner.class)PowerMockRunnerDelegate(Sputnik.class)PrepareForTest([SubService.class])class AbstractServiceTest extends Specification {Unroll def 测试抽象方法和实例方法() { given: mock抽象类方法 def sub PowerMockito.mock(SubService)// mock掉抽象类的parentMethod, 返回动态mock值:mockParentReturn PowerMockito.when(sub.parentMethod()).thenReturn(parentValue) PowerMockito.when(sub.doSomethingAndDao()).thenCallRealMethod() def moneyDAO Mock(MoneyDAO)//将Spockmock的对象moneyDAO使用powermock赋值给SubService的引用moneyDAO Whitebox.setInternalState(sub, moneyDAO, moneyDAO) moneyDAO.getExchangeByCountry(_) money // 这样就可以使用spock的动态mock expect: 调用doSomething方法 sub.doSomethingAndDao() result where: 验证分支场景 parentValue | money || resultparent1 | 100 || 100 CNYparent2 | 200 || 200 USDparent3 | 300 || 300 EURparent4 | 400 || 400 }}关于动态mock的更多用法可以参考这篇文章Spock高级用法 - 动态mock(完整的代码已上传到github在公众号里回复spock即可获取github项目地址)-END-推荐阅读Spock高级用法 - 动态mockSpock代码讲解 - 静态方法测试Spock代码讲解 - void方法测试Spock代码讲解 - 异常测试Spock代码讲解 - if esle 分支场景测试互联网一线java开发老兵工作10年有余梦想敲一辈子代码以梦为码不负韶华。扫码关注Java老K获取更多Java干货。