我爱编程

ionic 单元测试

2018-03-13  本文已影响601人  壹点微尘
Angular项目创建时,会自动生成spec.ts单元测试文件. 在ionic项目中, 需要手动创建spec.ts文件和添加依赖的框架.

添加配置依赖可以参看ionic-team写的一篇文章 :点我😄

单元测试基础入门

简单示例
describe('A suite is just function',()=>{
  var a;
  it('and so is a spec ', function () {
    a = true;
    expect(a).toBe(true);
  });
})

执行结果:


a 等于 true, 用例测试成功

上面的例子是一个很简单的单元测试, 它有三部分组成: describe() , it()expect()组成;

编写单元测试用例的基本步骤:
测试集

Jasmine中, 将功能相似的测试用例统一聚集在测试集(Suites)中, 并通过describe()函数标识. 假设被测试的业务类有多个函数, 则需要编写多个测试用例, 并将这些测试用例都放在同个 describe()函数中.

测试点

每个具体的功能测试点 (Spec) 可以用全局函数it()来定义, 该函数的第一个参数表示该用例的名称, 第二个参数为测试的细节. it()函数可以包含一个或者多个断言 (expect), 每个断言的结果只能是 true或者false, 只有当所有断言都为true是, 该测试点才算通过.

内置匹配器

内置匹配器(Matchers), 就是更在expect()函数后面, 用于判断结果是否符合期望值的函数. 在上面的例子中, 已经使用了一个很常用的匹配器toBe().

内置常用匹配器

toBe()本质是使用操作符 ===来比较结果值和期望值, not.toBe()则表示不等, 示例代码如下:

  it("The 'toBe()' matcher compares with '===' ", function () {
    var a = 15;
    var b = a;
    expect(a).toBe(b);
    expect(a).not.toBe(null);
  });
  it('should work for objects', function () {
    var foo = {
      a: 8,
      b: 15
    };

    var bar = {
      a: 8,
      b: 15
    }

    expect(foo).toEqual(bar);
  });
  it("The 'toMatch' matcher is for regular expressions", function () {
    var message = 'Ionic CLI and Cordova';
    expect(message).toMatch(/ionic/i);
  });
  it("The 'toContain' matcher is for finding an item in an array", function () {
    var array = ['React', 'Vue', 'Angular'];
    expect(array).toContain('Angular');
  });
Jasmine 内置匹配器:
匹配器 作用
toBe 使用 === 比较结果
toEqual 比较两个对象、数字、字符串等是否相等
toMatch 正则表达式匹配
toBeNull 验证是否为null
toBeTruthy 验证是否为 true
toBeFalsy 验证是否为 false
toBeLessThan 验证结果是否小于指定值
toBeGreaterThan 验证结果是否大于指定值
toContain 验证数组是否包含指定元素
toBeCloseTo 将值进行四舍五入后比较是否相等
toThrow 验证函数是否抛出一个错误
toThrowError 验证函数是否抛出指定的错误
toBeDefined 验证对象是否 不为 undefined
beforeEach 、afterEach函数

另外, 在测试中还会经常用到 beforeEach()afterEach() 这两个函数, 用于定义每个测试用例执行前及执行后的公共逻辑 。

beforeEach()的简单使用:

describe('How to use beforeEach', () => {

  let foo, bar;
  beforeEach(() => {
    foo = {
      a: 8,
      b: 15
    };

    bar = {
      a: 8,
      b: 15
    }
  })

  it('should work for objects', function () {
    expect(foo).toEqual(bar);
  });
})

单元测试

通过TestBed注入被测类

在上面的代码ll-mock-data.spec.ts中,我们使用到了TestBed.configureTestingModule(),它为我们创建了一个测试 NgModule,在它的元数据里面,我们可以注入被测试的类。如果有依赖,比如:Http,那么你需要 imports: [HttpModule],这一切都跟 NgModule 写法完全一置。

beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [LlMockDataProvider]
    });
});

组件 DOM 交互测试

在下面的图片中, 如果想检测DOM元素的内容是否符合我们的要求,
可通过TestBed进行组件的初始化, 可以获取组件模板对应的DOM元素以及检查 DOM元素的内容等。

示例代码如下:
page3.html

<ion-content no-padding>
  <ion-list>
    <button ion-item *ngFor="let item of list">
      {{item | llPhone}}
    </button>
  </ion-list>
</ion-content>

page3.ts

import {Component} from '@angular/core';
import {IonicPage, NavController, NavParams} from 'ionic-angular';

@IonicPage()
@Component({
  selector: 'page-page3',
  templateUrl: 'page3.html',
})
export class Page3 {
  list: string[] = ['15512345678'];
  constructor() {}
  ionViewDidLoad() {}
  addItem() {
    this.list.push(`15512345678`);
  }
}

page3.spec.ts

import {TestBed} from "@angular/core/testing";
import {Page3} from "./page3";
import {IonicModule} from "ionic-angular";
import {LlPhonePipe} from "../../pipes/ll-phone/ll-phone";

describe('Page3 组件', () => {

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [Page3, LlPhonePipe],
      imports: [
        IonicModule.forRoot(Page3)
      ],
    });
  });

  it('test simple component with TestComponentBuilder', () => {
    var fixture = TestBed.createComponent(Page3);
    var compiled = fixture.debugElement.nativeElement;

    // 调用 组件的 addItem() 函数
    fixture.componentInstance.addItem();
    // 变化监测
    fixture.detectChanges();

    // replace(/(^\s*)|(\s*$)/g, "") 移除字符串首尾空格
    let val = compiled.querySelector('.label').textContent.replace(/(^\s*)|(\s*$)/g, "");
    expect(val).toBe('155-1234-5678');
  });
});

在上面的代码中, 需要关注以下的知识点:

上一篇下一篇

猜你喜欢

热点阅读