Spock单元测试框架使用详解
2016-09-14 10:48
429 查看
Spock(Spock官网:http://spockframework.org/)作为java和Groovy测试一种表达的规范语言,其参考了Junit、Groovy、jMock、Scala等众多语言的优点,并采用Groovy作为其语法,目前能够在绝大多数的集成开发环境(如eclipse,Intellij
Ieda),构建工具(如Maven,gradle)等场景运行。Spock单元测试相对于传统的junit、JMockito、EsayMock、Mockito、PowerMock,由于使用了Groovy作为语法规则,代码量少,容易上手,提高了单元测试开发的效率,因此号称是下一代单元测试框架。
本文以实战的方式详解怎样使用Spock进行单元测试,以便更好地理解Spock单元测试,至少能够让读者能够在选择java单元测试面前多了一种选择。
1.2.1 接口类 BizService.java
1.2.2 接口实现类 BizServiceImpl.java
1.2.3 Dao层类 Dao.java
1.2.4 Bean数据类 PersonEntity.java
参考资料:
1.使用Spock框架进行单元测试;
2.Spock官网.
Ieda),构建工具(如Maven,gradle)等场景运行。Spock单元测试相对于传统的junit、JMockito、EsayMock、Mockito、PowerMock,由于使用了Groovy作为语法规则,代码量少,容易上手,提高了单元测试开发的效率,因此号称是下一代单元测试框架。
本文以实战的方式详解怎样使用Spock进行单元测试,以便更好地理解Spock单元测试,至少能够让读者能够在选择java单元测试面前多了一种选择。
1. 实战
1.1 Spock的Maven依赖:
<!-- Mandatory dependencies for using Spock --> <dependency> <groupId>org.spockframework</groupId> <artifactId>spock-core</artifactId> <version>1.1-groovy-2.4-rc-3</version> <scope>test</scope> </dependency> <!-- Optional dependencies for using Spock --> <dependency> <!-- use a specific Groovy version rather than the one specified by spock-core --> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy-all</artifactId> <version>2.4.7</version> </dependency> <dependency> <!-- enables mocking of classes (in addition to interfaces) --> <groupId>cglib</groupId> <artifactId>cglib-nodep</artifactId> <version>3.2.4</version> <scope>test</scope> </dependency> <dependency> <!-- enables mocking of classes without default constructor (together with CGLIB) --> <groupId>org.objenesis</groupId> <artifactId>objenesis</artifactId> <version>2.5.1</version> <scope>test</scope> </dependency>
1.2 构造项目基本代码
BizService.java(接口)、BizServiceImpl.java(接口实现类)、Dao.java(dao层代码)、PersonEntity.java(bean对象)1.2.1 接口类 BizService.java
/** * Created by zhangzh on 2017/2/25. */ package com.lance.spock.demo.api; public interface BizService { String insert(String id, String name, int age); String remove(String id); String update(String name, int age); String finds(String name); boolean isAdult(int age) throws Exception; }
1.2.2 接口实现类 BizServiceImpl.java
package com.lance.spock.demo.service.impl; import com.lance.spock.demo.api.BizService; import com.lance.spock.demo.dao.Dao; import com.lance.spock.demo.entity.PersonEntity; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; /** * Created by zhangzh on 2016/9/6. */ @Service public class BizServiceImpl implements BizService { @Autowired private Dao dao; public String insert(String id, String name, int age) { if (StringUtils.isAnyBlank(id, name)) { return ""; } PersonEntity bean = new PersonEntity(); bean.setAge(age); bean.setPersonId(id); bean.setPersonName(name); dao.insert(bean); return name; } public String remove(String id) { if (StringUtils.isBlank(id)) { return ""; } dao.remove(id); return id; } public String update(String name, int age) { if (StringUtils.isAnyBlank(name)) { return ""; } dao.update(name, age); return name; } public String finds(String name) { if (StringUtils.isBlank(name)) { return null; } List<PersonEntity> beans = dao.finds(name); StringBuilder sb = new StringBuilder(); sb.append("#"); for (PersonEntity bean : beans) { sb.append(bean.getAge()).append("#"); } return sb.toString(); } public boolean isAdult(int age) throws Exception { if(age < 0) { throw new Exception("age is less than zero."); } return age >= 18; } public Dao getDao() { return dao; } public void setDao(Dao dao) { this.dao = dao; } }
1.2.3 Dao层类 Dao.java
package com.lance.spock.demo.dao; import com.lance.spock.demo.entity.PersonEntity; import org.springframework.stereotype.Repository; import java.util.Arrays; import java.util.List; /** * Created by zhangzh on 2016/9/6. */ @Repository public class Dao { public void insert(PersonEntity bean) { System.out.println("Dao insert person"); } public void remove(String id) { System.out.println("Dao remove"); } public void update(String name, int age) { System.out.println("Dao update"); } public List<PersonEntity> finds(String name) { System.out.println("Dao finds"); PersonEntity bean = new PersonEntity(); bean.setPersonId("24336461423"); bean.setPersonName("张三"); bean.setAge(28); return Arrays.asList(bean); } }
1.2.4 Bean数据类 PersonEntity.java
/** * Created by zhangzh on 2016/9/6. */ package com.lance.spock.demo.entity; public class PersonEntity { private String personId; private String personName; private int age; public String getPersonId() { return personId; } public void setPersonId(String personId) { this.personId = personId; } public String getPersonName() { return personName; } public void setPersonName(String personName) { this.personName = personName; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "PersonEntity{" + "personId='" + personId + '\'' + ", personName='" + personName + '\'' + ", age=" + age + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; PersonEntity that = (PersonEntity) o; if (age != that.age) return false; if (personId != null ? !personId.equals(that.personId) : that.personId != null) return false; return personName != null ? personName.equals(that.personName) : that.personName == null; } @Override public int hashCode() { int result = personId != null ? personId.hashCode() : 0; result = 31 * result + (personName != null ? personName.hashCode() : 0); result = 31 * result + age; return result; } }
1.2.5 上下文配置 applicationContext.xml
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns="http://www.springframework.org/schema/beans" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.lance.spock.demo"/> </beans>
1.3. Test类 BizServiceTest.groovy
package com.lance.spock.demo.service.impl.groovy import com.lance.spock.demo.api.BizService import com.lance.spock.demo.dao.Dao import com.lance.spock.demo.entity.PersonEntity import com.lance.spock.demo.service.impl.BizServiceImpl import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.ApplicationContext import org.springframework.context.support.FileSystemXmlApplicationContext import spock.lang.Specification import spock.lang.Unroll /** * Created by zhangzh on 2017/2/25. */ public class BizServiceTest extends Specification { @Autowired private BizServiceImpl bizService; Dao dao = Mock(Dao) // 生成dao的Mock对象 /** * Spock和Junit类似也将单元测试划分成了多个阶段 * 如 setup() 类似于Junit的@Before,在这个方法中的代码块会在测试用例执行之前执行,一般用于初始化程序以及Mock定义 * * when:和then: 表示当...的时候,结果怎样. * * * * @return */ def setup() { println(" ============= test start =============") // 关联Mock对象,由于本测试是基于接口的测试,没有相应的setDao()方法,故采用此方法设置dao // ApplicationContext ac = new FileSystemXmlApplicationContext("classpath:applicationContext.xml"); bizService = ac.getBean(BizService.class) // bizService.h.advised.targetSource.target.dao = dao; bizService.setDao(dao) } def "test isAdult"() { setup: //setup: 代码块主要针对自己所在方法的初始化参数操作 int age = 20 when: bizService.isAdult(age) // 当执行isAdult方法时 then: true // 判断when执行bizService.isAdult(age)结果为true notThrown() // 表示没有异常抛出 println("age = " + age) } def "test isAdult except"() { expect: // expect简化了when...then的操作 bizService.isAdult(20) == true } def "age less than zero"() { setup: int age = -100 when: bizService.isAdult(age) then: def e = thrown(Exception) //thrown() 捕获异常,通常在then:中判断 e.message == "age is less than zero." println(e.message) cleanup: println("test clean up") // 单元测试执行结束后的清理工作,如清理内存,销毁对象等 } @Unroll // 表示根君where的参数生成多个test方法,如本例生成了2个方法,方法名称分别为: // 1."where blocks test 20 isadult() is true" // 2."where blocks test 17 isadult() is false" def "where blocks test #age isadult() is #result"() { expect: bizService.isAdult(age) == result where: // 其实实质是执行了两次"where blocks test"方法,但是参数不一样 age || result 20 || true 17 || false } def "insert test"() { setup: PersonEntity person = new PersonEntity(); person.setAge(28) person.setPersonId("id_1") person.setPersonName("zhangsan") when: bizService.insert("id_1", "zhangsan", 28) then: PersonEntity 1 * dao.insert(person) //判断dao执行了一次insert,且插入的对象是否equals } }
参考资料:
1.使用Spock框架进行单元测试;
2.Spock官网.
相关文章推荐
- 详解Python nose单元测试框架的安装与使用
- Spring整合JUnit框架进行单元测试代码使用详解
- Spring整合JUnit框架进行单元测试代码使用详解
- Spring整合JUnit框架进行单元测试代码使用详解
- Spring整合JUnit框架进行单元测试代码使用详解
- Spring整合JUnit框架进行单元测试代码使用详解
- socket通信框架mina使用详解(一)
- 详解Android首选项框架的使用
- AX 演示:使用单元测试框架测试类
- 在Struts中使用Validator验证框架详解
- 在 FlashDevelop4 中使用 ASUnit 单元测试框架
- 详解Android首选项框架的使用
- 使用Mootools开发JavaScript单元测试框架javascript
- 使用TestNG:基于注释的单元测试框架
- 对android应用进行单元测试使用单元测试框架
- 使用JUnit在struts+spring+hibernate框架环境下进行单元测试
- 使用 Visual Studio 2005 Team System 进行单元测试并生成用于 Unit Test Framework 的源代码(详解)
- 在dreamweaver中框架使用详解
- 使用Symbian OS Unit单元测试框架进行单元测试
- 使用JUnit在struts+spring+hibernate框架环境下进行单元测试