编写 angular2 测试并更改模拟返回值 - 使其干燥?

2024-02-12

我正在为服务编写一些测试,并且正在更改模拟函数的响应以测试各种情况。目前,每次我想要更改模拟的响应时,我都需要重置 TestBed 并再次配置测试模块,将我的新模拟作为依赖项注入。

我觉得必须有一种更干燥的方式来编写这个规范,但我无法弄清楚。有人有什么想法吗?

(我知道我可以将此服务作为标准 ES6 类编写测试,但我的组件和服务使用来自 Angular 的 Http 响应模拟内容,得到了相同的场景。)

这是我的规格文件:

import { TestBed, inject } from '@angular/core/testing';
import { Observable } from 'rxjs/Observable';
import { UserService, RestService } from '../index';
import { User } from '../../../models/index';


let getUserSpy = jasmine.createSpy('getUser');
let upsertUserSpy = jasmine.createSpy('upsertUser');


// NOTE that initally, the MockRestService throws errors for all responses
class MockRestService {
  getUser = getUserSpy.and.returnValue(Observable.throw('no thanks'));
  upsertUser = upsertUserSpy.and.returnValue(Observable.throw('no thanks'));
}


describe('User service - ', () => {

  let service;

  /**
   * First TestBed configuration
   */
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        UserService,
        {
          provide: RestService,
          useClass: MockRestService,
        }
      ]
    });
  });

  beforeEach(inject([UserService], (user: UserService) => {
    service = user;
  }));

  /* ... tests ... */

  describe('getUser/ upsertUser succeeds with INVALID user - ', () => {

    /**
     * Altering mock
     */
    class MockRestService {
      getUser = getUserSpy.and.returnValue(Observable.of({json: () => {
        return {name: 'dave'};
      }}));
      upsertUser = upsertUserSpy.and.returnValue(Observable.of({json: () => {}}));
    }

    /**
     * Reset and reconfigure TestBed. Lots of repetition!
     */
    beforeEach(() => {
      TestBed.resetTestingModule();
    });

    beforeEach(() => {
      TestBed.configureTestingModule({
        providers: [
          UserService,
          {
            provide: RestService,
            useClass: MockRestService,
          }
        ]
      });
    });

    beforeEach(inject([UserService], (user: UserService) => {
      service = user;
    }));

    /* ... tests ... */

  });

  describe('getUser/upsertUser succeeds with valid user', () => {
    const validResponse = {
      json: () => {
        return {
          firstName: 'dave',
          lastName: 'jones',
          email: '[email protected] /cdn-cgi/l/email-protection'
        };
      }
    };

    /**
     * Altering mock
     */
    class MockRestService {
      getUser = getUserSpy.and.returnValue(Observable.of(validResponse));
      upsertUser = upsertUserSpy.and.returnValue(Observable.of(validResponse));
    }

    /**
     * Reset and reconfigure testbed. Lots of repetition!
     */
    beforeEach(() => {
      TestBed.resetTestingModule();
    });

    beforeEach(() => {
      TestBed.configureTestingModule({
        providers: [
          UserService,
          {
            provide: RestService,
            useClass: MockRestService,
          }
        ]
      });
    });

    beforeEach(inject([UserService], (user: UserService) => {
      service = user;
    }));

    /* ... tests ... */

  });

});

它可能是一些变化

function setupUserTestbed() {
    beforeEach(() => {
      TestBed.configureTestingModule({...});
    });

    afterEach(() => {
      TestBed.resetTestingModule();
    });
 }

...
setupUserTestbed();
...
setupUserTestbed();

但目的是describe块(除了在测试报告中对规格进行分组之外)是为了安排before* and after*以最有效的方式阻止。

如果是顶级的话describe块有beforeEach块,您可以确定它会影响嵌套中的规格describe块。如果describe块是兄弟姐妹,共同行为应移至顶层describe。如果没有顶级describe对于兄弟姐妹describe块,应该创建它。

在发布的代码顶层describe('User service - ', () => { ... })已经有beforeEach块与TestBed.configureTestingModule, TestBed.resetTestingModule(它应该在afterEach) and inject。无需在嵌套中重复它们describe blocks.

食谱为MockRestService类与在规范之间交替的任何模拟相同。它应该是一个let/var多变的:

describe(...
  let MockRestService = class MockRestService { ... };

  beforeEach(() => { Testbed... });

  describe(...
    MockRestService = class MockRestService { ... };

    beforeEach(inject(...));

这种模式可以有很多变化。类本身可能是不变的,但是getUser and upsertUser属性可能会交替:

let getUserSpy;
let upsertUserSpy;

class MockRestService {
  getUser = getUserSpy;
  ...
}

describe(...

  beforeEach(() => { Testbed... });

  beforeEach(() => {
    getUserSpy = jasmine.createSpy().and.returnValue(...);
    ...
  });

  describe(...
    beforeEach(() => {
      getUserSpy = jasmine.createSpy().and.returnValue(...);
      ...
    });

    beforeEach(inject(...));

这也解决了一个重要问题,因为间谍在每个规范中都应该是新鲜的,即在beforeEach. getUserSpy and upsertUserSpy之后可以重新分配Testbed配置但之前inject(这是哪里MockRestService类可能被实例化)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

编写 angular2 测试并更改模拟返回值 - 使其干燥? 的相关文章

随机推荐