百日筑基第六十三天-使用Groovy+Spock写单测

百日筑基第六十三天-使用Groovy+Spock写单测

要使用Groovy+Spock编写单测,首先引入如下Maven依赖,同时安装Groovy插件。

<dependency>
     <groupId>org.spockframework</groupId>
     <artifactId>spock-core</artifactId>
     <version>1.2-groovy-2.4</version>
     <scope>test</scope>
 </dependency>

 <dependency>
     <groupId>org.spockframework</groupId>
     <artifactId>spock-spring</artifactId>
     <version>1.2-groovy-2.4</version>
     <scope>test</scope>
 </dependency>
 
 <dependency>
     <groupId>org.codehaus.groovy</groupId>
     <artifactId>groovy-all</artifactId>
     <version>2.4.7</version>
 </dependency>

接下来我们来讲一下Groovy的常见语法,作为一门动态语言,它的写法比Java简单很多,而且基本只要你会写Java,你很容易就可以上手Groovy。
首先看一下测试模板方法的定义和JUnit的对比:

在这里插入图片描述

Spock的模板方法说明:

def setupSpec() {}    // runs once -  before the first feature method
def setup() {}        // runs before every feature method
def cleanup() {}      // runs after every feature method
def cleanupSpec() {}  // runs once -  after the last feature method

常见用法

expect-where

有时,里面的某个测试用例失败了,却难以查到是哪个失败了。这时候,可以使用Unroll注解,该注解会将where子句的每个测试用例转化为一个 @Test 独立测试方法来执行,这样就很容易找到错误的用例。 方法名还可以更可读些。

@SpringBootTest(classes = BootstrapApplication)
@Transactional
@Rollback
class StaffQueryServiceSpec extends Specification {
	@Autowired
	private StaffQueryService staffQueryService;
	
	@Unroll
	def "通过归属人ID查询员工"(){
	expect:
	staffQueryService.getStaffById(ownerId)!=null
	where:
	ownerId | _
	1 | _
	2 | _
	}
}

where后面的条件可以通过表格的形式或者数据管道的形式,单个数据的时候可以通过“_”构建表格

def "通过归属人ID查询员工"(){
expect:
staffQueryService.getStaffById(ownerId)!=null
where:
ownerId << [1,2,3]
}
given-expect-where
@SpringBootTest(classes = BootstrapApplication)
@Transactional
@Rollback
class OrderQueryServiceSpec extends Specification {
	@Autowired
	private OrderQueryService orderQueryService;
	
@Unroll
 def "根据经销商机构判断是否存在在途订单"() {
	  given:
	  def orgId = 1
	  def dealerId = dealer
	  expect:
	  orderQueryService.hasOnWayOrder(dealerId, orgId) == result
	  where:
	  dealer | result
	  1        | true
	  9999     | false
 }
} 
given-when-then

这个比较符合敏捷开发中用户故事的描述,也是用的最多的一种写法。

@SpringBootTest(classes = BootstrapApplication)
@Transactional
@Rollback
class OrderAppServiceSpec extends Specification {
	@Autowired
	private OrderAppService orderAppService;
	
def "取消订单"() {
        given:
        def dto = new CancelOrderDTO(operatorId: "1", operatorName: "tzx", dealerId: 1)
        when:
        dto.setOrderNo("OR202001020014")
        orderAppService.cancelOrder(dto)
        then:
        noExceptionThrown()
        when:
        dto.setOrderNo("OR202001020010")
        orderAppService.cancelOrder(dto)
        then:
        thrown(Exception)
    }
}    
given-when-then-where
@SpringBootTest(classes = BootstrapApplication)
@Transactional
@Rollback
class OrderAppServiceSpec extends Specification {
	@Autowired
	private OrderAppService orderAppService;
	
def "取消订单"() {
        given:
        def dto = new CancelOrderDTO(operatorId: operatorId, operatorName: operatorName, dealerId: dealerId)
        when:
        dto.setOrderNo("OR202001020014")
        orderAppService.cancelOrder(dto)
        then:
        noExceptionThrown()
        where:
        operatorId| operatorName | dealerId
        1| "tzs" | 1
        2| "zhangsan" | 1
        3 | "wangwu" | 2
    }
}    

如果有多个条件需要测试时可以采用这种写法

given-when-then-thrown

在 when 子句中调用了会抛出异常的方法,而在 then 子句中,使用 thrown 接收方法抛出的异常,并赋给指定的变量 ex, 之后就可以对 ex 进行断言了。

@SpringBootTest(classes = BootstrapApplication)
@Transactional
@Rollback
class CustomerAppServiceSpec extends Specification {
	@Autowired
	private CustomerAppService customerAppService;
	
	def "更新未存在客户" (){
	 given:
	 def dto = new CustomerCreateDTO(customerId: -1,customerName: "小王");
	 when: "客户不存在时"
	 customerAppService.updateCustomer(dto);
	 then:
	 def ex = thrown(ConnectorBusinessException)
	 ex.class.name = "java.lang.RuntimeException"
	 ex.cause.class.name = "com.souche.connector.common.exception.ConnectorBusinessException"
	}
}
打桩

很多时候我们测试的时候不需要执行真正的方法,因为在测试代码里面构建一个真实的对象是比较麻烦的,特别是使用一些依赖注入框架的时候,因此有了打桩的功能。
比如我们依赖某个外部应用的service的返回值,可以采用如下的方式。

@SpringBean
 UserCenterQueryService userCenterQueryService = Mock{
     getUserByShopCodeAndRole(_,_) >> "001"
 };

如果需要定义多次调用返回不同的返回值可以采用下面的方式

@SpringBean
UserCenterQueryService userCenterQueryService = Mock{
    getUserByShopCodeAndRole(_,_)  >>>  ["001","002"]
};
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值