- 传统方式得痛点
使用传统方式开发人员拿到需求进行构思然后coding,有得时候开发得时候就会发现某些问题无法解决不得不推翻想法从头来过,当解决了一切,项目看似正常运行了,一般开发人员都不会想着把功能进行测试一次。
如果是前后台分离的项目,缺点更加明显,前台没法进行模拟接口,只能编写静态页面,等待后台接口编写完成再进行调整,往往这个过程是相当漫长的。 - 使用TDD(测试驱动开发)模式,可以在整理需求的时候将接口、测试类编写完成,所有的测试都要独立,并且速度要快,也就意味着测试中严禁有使用spring框架进行bean的加载,可以使用mock进行模拟,这个时候的测试类全部都是失败,我们就是需要编写实现代码将测试类全部跑通,然后进行代码优化,这样做的好处是1.前端可以根据预先定义好的接口说明进行模拟开发,后期接入真实接口使调试过程大大降低,2.后台代码质量提高,开发人员需将所有测试类跑通才能进行git提交。
使用TDD模式需要转变的观念有,前台使用的数据结构为VO而不是传统方式的DBO,service层可能会有大部分set,这个可以通过部分设计模式减轻该情况。 - java端开发过程中使用junit的测试示例
3.1.引入依赖
<properties>
<moke.version>2.11.0</moke.version>
<junit.version>4.12</junit.version>
</properties>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jmock</groupId>
<artifactId>jmock</artifactId>
<version>${moke.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jmock</groupId>
<artifactId>jmock-legacy</artifactId>
<version>${moke.version}</version>
<scope>test</scope>
</dependency>
3.2.dbo
@Data
public class Student {
private String id;
private String name;
private String sex;
private Integer age;
}
3.3.vo
@Data
public class StudentInfo {
private String name;
private String sex;
private Integer age;
}
3.4.repository
@Repository
public class StudentRepository {
public int add(Student student){
return 0;
}
}
3.5.service
@Service
public class StudentService {
private StudentRepository studentRepository;
public StudentService(StudentRepository studentRepository){
this.studentRepository = studentRepository;
}
public String addStudent(StudentInfo studentInfo){
Student student = PropertyPadding.change(studentInfo, Student.class);
int num = studentRepository.add(student);
if(num > 0){
return "ok";
}else {
return "error";
}
}
}
3.6.属性绑定工具类
public class PropertyPadding{
public static<T> T change(Object object, Class<T> tClass) {
Class classA = object.getClass();
T classB = null;
try {
classB = tClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
//此处省略将classA属性数据绑定到classB属性过程
return classB;
}
}
3.7.测试类 所有的测试方法都得是test开头的,方便后面的集中测试
@RunWith(JUnit4.class)
public class StudentServiceTest extends TestCase {
private StudentRepository studentRepository;
private StudentInfo studentInfo;
private StudentService studentService;
@Before
public void init(){
studentInfo = new StudentInfo();
final Student student = PropertyPadding.change(studentInfo, Student.class);
Mockery mockery = new Mockery();
studentRepository = mockery.mock(StudentRepository.class);
mockery.checking(new Expectations(){
{
exactly(1).of(studentRepository).add(student);
will(returnValue(1));
}
});
studentService = new StudentService(studentRepository);
}
@Test
public void testAddStudent(){
studentService.addStudent(studentInfo);
}
}
-
前端使用mocke模拟接口数据的示例
1.安装mockjs, npm install mockjs --save-dev
2.配置
config目录下dev.env.js‘use strict’
const merge = require(‘webpack-merge’)
const prodEnv = require(’./prod.env’)module.exports = merge(prodEnv, {
NODE_ENV: ‘“development”’,
Mock: true
})
config目录下prod.env.js‘use strict’
module.exports = {
NODE_ENV: ‘“production”’,
Mock: false
}
src目录下main.js添加
process.env.Mock && require(’./mock/mock.js’)
在src目录下创建mock目录,这个下面保存mock数据
可以举一个例子
const Mock = require('mockjs')
// 获取 mock.Random 对象
const Random = Mock.Random
// mock一组数据
const produceNewsData = function () {
let articles = []
for (let i = 0; i < 100; i++) {
let newArticleObject = {
title: Random.csentence(5, 30), // Random.csentence( min, max )
thumbnail_pic_s: Random.dataImage('300x250', 'mock的图片'), // Random.dataImage( size, text ) 生成一段随机的 Base64 图片编码
author_name: Random.cname(), // Random.cname() 随机生成一个常见的中文姓名
date: Random.date() + ' ' + Random.time() // Random.date()指示生成的日期字符串的格式,默认为yyyy-MM-dd;Random.time() 返回一个随机的时间字符串
}
articles.push(newArticleObject)
}
return {
data: articles
}
}
// 拦截ajax请求,配置mock的数据
Mock.mock('/api/test', 'get', produceNewsData)