关于java:Spock单元测试框架实战指南五-void方法测试

51次阅读

共计 2371 个字符,预计需要花费 6 分钟才能阅读完成。

本篇解说如何针对 void 办法,即无返回后果的办法测试

void 办法

void 办法的测试不能像后面几篇介绍的那样在 then 标签里验证返回后果,因为 void 办法没有返回值

一般来说无返回值的办法,外部逻辑会批改入参的属性值,比方参数是个对象,那代码里可能会批改它的属性值,尽管没有返回,但还是能够通过校验入参的属性来测试 void 办法

还有一种更无效的测试形式,就是验证办法外部逻辑和流程是否合乎预期,比方:

  • 应该走到哪个分支逻辑?
  • 是否执行了这一行代码?
  • for 循环中的代码执行了几次?
  • 变量在办法外部的变动状况?

先看一个 void 办法的业务代码示例:

/**
 * 依据汇率计算金额
 * @param userVO
 */
public void setOrderAmountByExchange(UserVO userVO){if(null == userVO.getUserOrders() || userVO.getUserOrders().size() <= 0){return ;}
    for(OrderVO orderVO : userVO.getUserOrders()){BigDecimal amount = orderVO.getAmount();
        // 获取汇率(调用汇率接口)
        BigDecimal exchange = moneyDAO.getExchangeByCountry(userVO.getCountry());
        amount = amount.multiply(exchange); // 依据汇率计算金额
        orderVO.setAmount(amount);
    }
}

这个 void 办法次要是遍历 userVO 上面的订单,通过调用汇率接口计算订单的外币金额,而后再赋值给 userVO.orderVO.amount,所以他的外围逻辑在for 循环里,那么咱们的测试重点就是验证 for 循环外面的逻辑是否合乎预期,金额计算是否正确

代码实现

间接看 Spock 的测试代码如何写:

/**
 * 用户服务测试类
 * @author 公众号:Java 老 K
 * 集体博客:www.javakk.com
 */
class UserServiceTest extends Specification {def userService = new UserService()
    def moneyDAO = Mock(MoneyDAO)

    void setup() {
        userService.userDao = userDao
        userService.moneyDAO = moneyDAO
    }

    def "测试 void 办法"() {
        given: "设置申请参数"
        def userVO = new UserVO(name:"James", country: "美国")
        userVO.userOrders = [new OrderVO(orderNum: "1", amount: 10000), new OrderVO(orderNum: "2", amount: 1000)]

        when: "调用设置订单金额的办法"
        userService.setOrderAmountByExchange(userVO)

        then: "验证调用获取最新汇率接口的行为是否合乎预期: 一共调用 2 次, 第一次输入的汇率是 0.1413, 第二次是 0.1421"
        2 * moneyDAO.getExchangeByCountry(_) >> 0.1413 >> 0.1421

        and: "验证依据汇率计算后的金额后果是否正确"
        with(userVO){userOrders[0].amount == 1413
            userOrders[1].amount == 142.1
        }
    }
}

次要是 then 标签里的语法: 2 * moneyDAO.getExchangeByCountry(_) >> 0.1413 >> 0.1421,这行代码示意 moneyDAO 的 getExchangeByCountry() 办法会被执行 2 次,第一次输入的后果是 0.1413,第二次输入的接口是 0.1421

2 * moneyDAO.getExchangeByCountry(_) >> 0.1413 >> 0.1421这行代码也能够离开写,比方只写后面的2 * moneyDAO.getExchangeByCountry(_)

“2 * ” 示意办法理论执行的次数,如果不是 2 次则不合乎预期,单元测试会失败,看你具体的传参,比方在 given 标签里咱们结构的 user 上面有 2 个 order,订单号别离是 1,2,金额别离是 1w,1k

那么在调用 void 办法时,for 循环就会循环 2 次,所以能够通过这样的写法验证咱们调用汇率接口的办法是否执行了,以及执行次数

最初在 with() 办法里会对入参 userVO 里的订单金额 amount 进行校验,因为咱们设置的两单订单金额别离是 1w 和 1k,then 标签曾经对汇率接口的返回后果 mock 了 2 个不同的汇率值:0.1413、0.1421,那么转换后的外币金额就是 1413 和 142.1 元

你也能够将代码改成1 * moneyDAO.getExchangeByCountry(_),而后运行单测,会提醒相应的错误信息:

报错信息阐明理论执行 (invoke) 了 2 次

执行几次就写几次,没有执行过就是 ”0 * “,这正是 BDD 行为驱动开发 思维的体现

(power mock 的 thenVerify() 也能够实现这样的性能,只不过 Spock 语法更简洁一些)

void + where

如果要联合 where 测试多分支的 void 办法时,须要留神一点,因为 Spock 要求 where 标签里的表格至多含有两列,如果你的 where 只是验证入参,也就是只有一列须要验证,那么能够用 ”_” 示意另外一列值,代码相似上面这样的写法:

where:
requsetParam | _
userVO1      | _
userVO2      | _
userVO3      | _

应用“_”示意任意输出或输入

文章起源:http://javakk.com/297.html

正文完
 0