所有文章,首发于优快云-柠檬加冰博客
测试controller和service准备工作
准备工作
项目搭建
你已经按照上一篇文章,创建了ionic-tests工程,并在工程中加载了karma测试用例,完成了项目搭建、测试工作。
如果没有,请参考ionic之如何应用karma进行单元测试
开始测试
理解karma和jasmine
Jasmine is a behavior-driven development framework for testing JavaScript code. It does not depend on any other JavaScript frameworks. It does not require a DOM. And it has a clean, obvious syntax so that you can easily write tests.
jasmine是一个行为驱动开发的测试框架,不依赖任何js框架以及dom,是一个非常干净以及友好API的测试库.
下面简单的以一个例子来说明它的用法
在之前创建的controller.test.js中,增加下面的代码
//最简单的karma测试
describe("A spec (with setup and tear-down)", function () {
var foo;
//在测试用例执行前加载
beforeEach(function () {
foo = 0;
foo += 1;
});
//在测试用例执行后加载
afterEach(function () {
foo = 0;
});
//测试用例
it("is just a function, so it can contain any code", function () {
//expect括号中是需要测试的函数,或是变量
//toEqual括号中是期望的函数返回值或是变量值
expect(foo).toEqual(1);
});
//测试用例--单个测试用例中,可以增加多个测试项
it("can have more than one expectation", function () {
expect(foo).toEqual(1);
expect(true).toEqual(true);
});
});
代码中,基本上把jasmineAPI的一些相关属性都做了注释,下面对核心的功能点进行简单的介绍:
首先任何一个测试用例以describe函数来定义,它有两参数,第一个用来描述测试大体的中心内容,第二个参数是一个函数,里面写一些真实的测试代码
it是用来定义单个具体测试任务,也有两个参数,第一个用来描述测试内容,第二个参数是一个函数,里面存放一些测试方法
expect主要用来计算一个变量或者一个表达式的值,然后用来跟期望的值比较或者做一些其它的事件
beforeEach与afterEach主要是用来在执行测试任务之前和之后做一些事情,上面的例子就是在执行之前改变变量的值,然后在执行完成之后重置变量的值
最后要说的是,describe函数里的作用域跟普通JS一样都是可以在里面的子函数里访问的,就像上面的it访问foo变量
测试controllers里面的变量和函数
新增代码
在controller.test.js中,加入下面的代码
//ng controller的单元测试
describe('test ng controller', function () {
//设置测试用例的变量
//作用域包括整个用例
var scope;
var chatsServiceMock;
//加载controller
beforeEach(module('starter.controllers'));
//因为controller中注入了services的模块,所以也要加载services模块
beforeEach(module('starter.services'));
//将所需模块注入到测试用例中
beforeEach(inject(function ($rootScope, $controller, _Chats_) {
scope = $rootScope.$new();
chatsServiceMock = _Chats_;
$controller('ChatsCtrl', {$scope: scope, Chats: _Chats_});
}));
//以下为测试用例
it('should have scopeMock defined', function () {
expect(scope).toBeDefined();
});
it('should get an instance of ChatsService', function () {
expect(chatsServiceMock).toBeDefined();
});
//测试remove功能,该功能的需求是,
// 原有5条信息,执行完功能函数后,
// services保存的数据和controller数组中保存的数据减1,变为4
it('should delete a person in chats', function () {
var chat = {
id: 0,
name: 'Ben Sparrow',
lastText: 'You on your way?',
face: 'img/ben.png'
};
scope.remove(chat);
expect(chatsServiceMock.all().length).toBe(4);
expect(scope.chats.length).toBe(4);
});
});
具体的解释,可以参考里面的注释,自我感觉写的已经比较清楚了,有不明白的地方可以留言交流。
karma测试
karma start tests/my.conf.js
测试services
新增代码
describe('Chats Unit Tests', function(){
var Chats;
beforeEach(module('starter.services'));
beforeEach(inject(function (_Chats_) {
Chats = _Chats_;
}));
it('can get an instance of my factory', inject(function(Chats) {
expect(Chats).toBeDefined();
}));
it('has 5 chats', inject(function(Chats) {
expect(Chats.all().length).toEqual(5);
}));
it('has Max as friend with id 1', inject(function(Chats) {
var oneFriend = {
id: 1,
name: 'Max Lynx',
notes: 'Hey, it\'s me',
face: 'img/max.png'
};
expect(Chats.get(1).name).toEqual(oneFriend.name);
}));
});
karma测试
karma start tests/my.conf.js