Angualr单元测试

Angualr单元测试

Angular自己的单元测试工具:Karma + Jasmine

  • Karma:是自动化测试管理工具,可以监控文件,唤起关闭浏览器自动执行测试。
  • Jasmine:用来编写JavaScript测试的框架。

概念

Test Suite
  • 作用:将若干测试用例集合在一个分类下就叫测试套件
  • describe全局函数来表示,
    1. 它的第一个字符串参数,用来表示Suite的名称或标题
    2. 第二个方法参数就是实现Suite代码了
describe('test suite name', () => {
});
Specs
  • 作用:一个Specs相当于一个测试用例
  • it全局函数来表示,和describe类似,字符串和方法两个参数。

每个测试用例包括多个exception来测试需要测试的代码,只要任何一个断言的结果为false就表示该测试用例为失败状态。

Expectations

断言,使用expect全局函数来表示,只接受一个代表要测试的实际值,并且需要与Matcher代表期望值

常用方法

Matches

断言匹配操作,在实际值与期望值之间进行比较,并将结果通知Jasmine,最终Jasmine会判断此用例成功还是失败。

常用Matchers

  • toBe(): === 基本类型判断
  • toNotBe(): !==
  • toBeDefined():!== undefined
  • toBeUndefined(): === undefined
  • toBeNull(): === null
  • toBeTruthy(): !!obj 判断是否能转换成bool型,判断是否是true
  • toBeFalsy(): !obj
  • toBeLessThan(): <
  • toBeGreaterThan(): >
  • toEqual(): 有两种用法,1. 对于基本的类型,相当于toBe(); 2. 还可以用来判断对象;
  • toNotEqual():
  • toContain() indexOf 判断集合是否包含(可以是普通类型,可以是对象)
  • toHaveBeenCalled(): 检查function是否被调用过
  • toHaveBeenCalledWith(): 检查传入参数是否被作为参数调用过
  • toMatch(): new RegExp().text() 使用正则表达式判断
  • ToNotMatch(): 等同!new RegExp().text()
  • toThrow(): 检查function是否会抛出一个错误
  • toBeCloseTo: 判断数字

这些API之前可以用not来表示负值的判断

Setup与Teardown

将重复的setup与teardown代码,放在与之相对应的beforEach与afterEach全局函数里面

describe('demo test', () => {
    let val: number = 0;
    beforeEach(() => {
        val = 1;
    });
    it('should be true', () => {
        expect(val).toBe(1);
    });
    it('should be false', () => {
        expect(val).not.toBe(0);
    });
});
嵌套代码

describe可以相互嵌套

跳过测试代码

xdescribe xit

配合Angualr工具集

Spy

为了测试自定义事件是否正常被调用,是非常重要的。Spy可以用来监测函数是否被调用,这简直就是我们的好伙伴。

describe('AppComponent', () => {
    let fixture: ComponentFixture;
    let context: TestComponent;

    beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [TestComponent]
        });
        fixture = TestBed.createComponent(TestComponent);
        context = fixture.componentInstance;
        // 监听onSelected方法
        spyOn(context, 'onSelected');
        fixture.detectChanges();
    });

    it('should be called [selected] event.', () => {
        // 触发selected操作

        // 断言是否被调用过
        expect(context.onSelected).toHaveBeenCalled();
    });
});

Spy用来追踪函数的调用历史信息(是否被调用,调用参数列表,被请求次数等)。Spy仅存在于定义它的describe和it方法块中,并且每次在测试用例执行完后被销毁

spy常用
  1. and.callThrough()在使用spy的同时也会执行实际的代码。

  2. and.returnValue()由于spy是模拟函数的调用,因此我们也可以强制指定函数的返回值。

  3. and.callFake()和returnValue相似,callFake则更进一步,直接通过指定一个假的自定义函数来执行。比returnValue更灵活,我们可以任意捏造一个函数来达到我们的测试要求

     spyOn(foo, "getBar").and.callFake(function() {
              return 1001;
     });
    
  4. and.thorwErrow模拟异常的抛出;

  5. and.stub重置spy

其他追踪属性

calls: 对于被spy的函数的调用,都可以在calls属性中跟踪

  • .calls.any():被Spy的函数一旦被调用过,则返回true,否则为false
  • .calls.count():返回被Spy的函数的被调用次数
  • .calls.argsFor(index):返回被spy的函数的调用参数,以index来指定参数
  • .calls.allArgs:返回被spy的函数的所有调用参数;
  • .callls.all(): 返回calls的上下文,将返回当前calls的整个实例数据;
  • .calls.mostRecent():返回calls中追踪的最近一次的请求数据;
  • .calls.first():返回calls中追踪的第一次请求的数据;
  • .object: 当调用all(),mostRecent(),first()方法时,返回对象的object属性返回的是当前上下文对象
  • .calls.reset(): 重置spy的所有追踪数据;
createSpy
createSpyObj

异步支持

首先,这里的异步是指带有Observable或promise的异步行为,因此对于组件在调用某个Service来异步获取数据的时候测试状态

async

async无任何参数与返回值,所有包裹在代码块里的测试代码,可以通过调用whenStable()让所有异步行为都完成后再进行回调:最后,再进行断言操作。

it('should be get user list (async)', async(() => {
    // call component.query();
    fixture.whenStable().then(() => {
        fixture.detectChanges();
        expect(true).toBe(true);
    });
}));
fakeAsync

将回调换成tick()

it('should be get user list (async)', fakeAsync(() => {
    // call component.query();
    tick();
    fixture.detectChanges();
    expect(true).toBe(true);
}));
Jasmine自带异步
  1. 前面的异步是指Observable或Promise的异步行为
  2. setTimeout或者可能是需要外部订阅结果以后才能触发done()方法
it('async demo', (done: () => void) => {
    context.show().subscribe(res => {
        expect(true).toBe(true);
        done();
    });
    el.querySelected('xxx').click();
});

你可能感兴趣的:(Angualr单元测试)