乐趣区

关于前端:Angular-进行简单单元测试

前言

之前对单元测试的认知就是简单,难搞,思路有,就是不晓得怎么去实现,最近一次散会解决问题的过程中,发现原来单元测试能够非常简略,简略到几行代码就能实现。

示例

上面代码实现的性能是,判断课程所在的学院 <College> college 是否在用户所有的学院 Array<College> colleges 中,如果存在,变量 show 赋值为 true,不存在,则赋值为 false,如果 college 为 undefined 或者 null,也赋值为 true。

 /**
   * 察看课程学院是否与用户所在学院雷同
   * @param college 课程学院
   * @param colleges 用户学院
   */
  public whetherShow(college: { id: number}, colleges: Array<{id: number}>) {Assert.notNull(college, 'college 未定义');
    const collegeId = college.id;
    let show = colleges != null && colleges && colleges.length > 0 ? false : true;
    if (colleges != null) {
      colleges.forEach(selectCollege => {if (collegeId === selectCollege.id) {show = true;}
      });
    }
    return show;
  }

要对该办法进行单元测试,思路就是传值进去进行比照,重点在于传值,用之前的思路就是,定义 college 和 colleges, 而后进行比照:

it('is show', () => {const course = new Course({id: 1})
    const collegeOne  = new College({id: 1});
    const collegeTwo = new College({id: 2});
    component.colleges = [];
    expect(component.whetherShow(course,component.colleges)).toBe(true);
    component.colleges = undefined;
    expect(component.whetherShow(course,component.colleges)).toBe(true);
    component.colleges = [collegeOne];
    expect(component.whetherShow(course,component.colleges)).toBe(true);
    component.colleges = [collegeTwo];
    expect(component.whetherShow(course,component.colleges)).toBe(false);
    component.colleges = [collegeOne, collegeTwo];
    expect(component.whetherShow(course,component.colleges)).toBe(true);
  });


通过控制台的信息能够发现,无论是 null 还是 undefined,都是能够通过的,起初老师提供了新的思路,既然要测试的是性能,就不要管怎么传的,能够不必传对象,而后就有了上面的写法:

  it('is show', () => {expect(component.whetherShow({id: 1}, null)).toBe(true);
    expect(component.whetherShow({id: 1}, undefined)).toBe(true);
    expect(component.whetherShow({id: 1}, [])).toBe(true);
    expect(component.whetherShow({id: 1}, [{id: 2}, {id: 3}])).toBe(false);
    expect(component.whetherShow({id: 1}, [{id: 1}, {id: 2}, {id: 3}])).toBe(true);
    expect(component.whetherShow({id: 1}, [{id: 2}, {id: 3}, {id: 1}])).toBe(true);
  });

值传进去了,办法也能判断了,比起之前的写法几乎要好太多,而且对于一些办法来说,这种办法省力不少,尤其是对多种状况进行测试,要进行多个变量的定义:

 /**
   * 判断查问的关键字是否课程代码或名称中
   * @param course 课程
   * @param searchKey 查问关键字
   */
  public isCodeOrNameContainsSearchKey(course: { code: string, name: string}, searchKey: string) {
    return searchKey === null
      || course.code.toLowerCase().indexOf(searchKey.toLowerCase()) !== -1
      || course.name.toLowerCase().indexOf(searchKey.toLowerCase()) !== -1;
  }

该办法实现的是通过课程名称或代码进行查问操作,通过对查问关键字和课程名称或代码进行比照实现该性能,要思考以下几种状况:查问关键字为 null、查问关键字与课程名称或代码局部齐全不雷同、查问关键字与课程名称或代码局部雷同、查问关键字与课程名称或代码完全相同、查问关键字蕴含课程名称或代码。
如果用旧思想进行测试:

 it('isCodeOrNameContainsSearchKey', () => {const courseOne = new Course({code: '', name:''});
    const courseTwo = new Course({code: '222', name: ''});
    const courseThree = new Course({code: '', name:'222'});
    const courseFour = new Course({code: '222', name: '222'});
    expect(component.isCodeOrNameContainsSearchKey(courseOne, null));
    expect(component.isCodeOrNameContainsSearchKey(courseOne, ''));
    expect(component.isCodeOrNameContainsSearchKey(courseTwo, ''));
    expect(component.isCodeOrNameContainsSearchKey(courseTwo, '1111'));
    expect(component.isCodeOrNameContainsSearchKey(courseTwo, '22'));
    expect(component.isCodeOrNameContainsSearchKey(courseTwo, '222'));
    expect(component.isCodeOrNameContainsSearchKey(courseTwo, '2222'));
    expect(component.isCodeOrNameContainsSearchKey(courseThree, ''));
    expect(component.isCodeOrNameContainsSearchKey(courseThree, '1111'));
    expect(component.isCodeOrNameContainsSearchKey(courseThree, '22'));
    expect(component.isCodeOrNameContainsSearchKey(courseThree, '222'));
    expect(component.isCodeOrNameContainsSearchKey(courseThree, '2222'));
    expect(component.isCodeOrNameContainsSearchKey(courseFour, ''));
    expect(component.isCodeOrNameContainsSearchKey(courseFour, '1111'));
    expect(component.isCodeOrNameContainsSearchKey(courseFour, '22'));
    expect(component.isCodeOrNameContainsSearchKey(courseFour, '222'));
    expect(component.isCodeOrNameContainsSearchKey(courseFour, '2222'));
    
});

如果应用新思维:

  it('isCodeOrNameContainsSearchKey', () => {expect(component.isCodeOrNameContainsSearchKey({code: '', name:''}, null)).toBe(true);
    expect(component.isCodeOrNameContainsSearchKey({code: '', name:''}, '')).toBe(true);
    expect(component.isCodeOrNameContainsSearchKey({code: '222', name: ''},'')).toBe(true);
    expect(component.isCodeOrNameContainsSearchKey({code: '222', name: ''},'1111')).toBe(false);
    expect(component.isCodeOrNameContainsSearchKey({code: '222', name: ''},'22')).toBe(true);
    expect(component.isCodeOrNameContainsSearchKey({code: '222', name: ''},'222')).toBe(true);
    expect(component.isCodeOrNameContainsSearchKey({code: '222', name: ''},'2222')).toBe(false);
    expect(component.isCodeOrNameContainsSearchKey({code: '', name:'222'},'')).toBe(true);
    expect(component.isCodeOrNameContainsSearchKey({code: '', name:'222'},'1111')).toBe(false);
    expect(component.isCodeOrNameContainsSearchKey({code: '', name:'222'},'22')).toBe(true);
    expect(component.isCodeOrNameContainsSearchKey({code: '', name:'222'},'222')).toBe(true);
    expect(component.isCodeOrNameContainsSearchKey({code: '', name:'222'},'2222')).toBe(false);
    expect(component.isCodeOrNameContainsSearchKey({code: '222', name: '222'}, '')).toBe(true);
    expect(component.isCodeOrNameContainsSearchKey({code: '222', name: '222'}, '1111')).toBe(false);
    expect(component.isCodeOrNameContainsSearchKey({code: '222', name: '222'}, '22')).toBe(true);
    expect(component.isCodeOrNameContainsSearchKey({code: '222', name: '222'}, '222')).toBe(true);
    expect(component.isCodeOrNameContainsSearchKey({code: '222', name: '222'}, '2222')).toBe(false);
  });

构想一下本人看到别人写的测试代码,如果所须要的变量很少,courseOne 等等能满足需要,看着也没问题,然而当变量很多的时候,预计写测试的都会遗记每个变量的属性值,更不用说看的人,而且,应用上面的办法写的代码,所需字段以及字段值高深莫测,一行代码就能体现所有信息,看着也赏心悦目。

总结

简略的单元测试写起来真的要简略很多,而且感觉比之前的要优雅很多,看起来真的挺整洁的,整整齐齐的看着很难受,感激潘老师的领导,也感激小伙伴们给予的帮忙。


本文作者:河北工业大学梦云智开发团队 张文达

退出移动版