spy间谍函数

前言

我们在进行单元测试时,尽可能的将每个功能点拆分成独立的可测试的小功能。力求测试点的最小化。这样不仅测试时减少思维量,也使得对测试代码的修正简单。有时当我们无法对某个函数是否执行进行测试时,我们就需要用到间谍函数。

例子

情景引入

ngOnInit() {
    this.loadData();
  }

  /*查询*/
  onQuery() {
    this.loadData(); // 直接调用数据加载函数
  }

  loadData() {
    const queryParams = {
      page: this.params.page,
      size: this.params.size,
      klassId: this.params.klass.id,
      name: this.params.name.value,
      sno: this.params.sno.value
    };
    ...
  }

当我们本着不造重复的轮子的原则对ngOnInit方法和onQuery方法相同部分写到一个方法里,再分别进行调用时。我们发现测试变成了loadData是否正确执行和ngOnInit方法和onQuery方法是否正确调用loadData方法两步,而后者如何进行测试呢?angular为我们提供了spyOn()方法。

替身方法

spyon方法使用方法如下

spyOn(Math, 'random').andReturn(0.1);

spyon有监听的意思,这句话的意思是说,当我们调用math类的random方法时,返回0.1.
回到我们的测试中来,我们可以这样测试onQuery方法是否调用了loadData方法

describe('Student -> IndexComponent', () => {
  ...
  fit('onQuery', () => {
    spyOn(component, 'loadData');

    component.onQuery();
    expect(component.loadData).toHaveBeenCalled(); 
  });

});

我们对loadData方法进行监听,一旦被调用,我们就可以通过断言判别。
spyOn方法就像一个间谍,监听指定的方法,当有人调用这个方法时,截取他,让他不调用真正的方法,当调用此方法时实际上调用的为该方法的替身。
spy间谍函数_第1张图片

替身类

我们除了可以方法构造替身外,还可以对类构造替身

beforeEach(async(() => {
    const routerSpy = jasmine.createSpyObj('Router', ['navigateByUrl']);

    TestBed.configureTestingModule({
      declarations: [EditComponent],
      imports: [
        ReactiveFormsModule,
        HttpClientTestingModule,
        RouterTestingModule
      ],
      providers: [
        {provide: ActivatedRoute, useClass: ActivatedRouteStub},
        {provide: Router, useValue: routerSpy}
      ]
    })
      .compileComponents();
  }));

他创建了一个router的替身,并且该替身含有navigateByUrl方法。这时我们需要在providers中进行声明,当调用Router时,用routerSpy。
当我们使用时

 fit(‘', () => {
   ...
   const routerSpy: SpyObj = TestBed.get(Router); 
      expect(routerSpy.navigateByUrl.calls.any()).toBe(false); 
      req.flush(null, {status: 204, statusText: 'No Content'});
      expect(routerSpy.navigateByUrl.calls.any()).toBe(true); 
  });

在调用时,我们需要先获取替身。我们定义时声明为SpyObj类型,在使用时也应是SpyObj类型。

总结

我们在测试时要善于使用方法进行测试,可以用替身的,坚决不用真身。

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