写angular2测试并更改模拟返回值 - 让它干?

时间:2017-01-10 11:33:30

标签: angular unit-testing jasmine angular2-testing

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

我觉得必须有一个DRYer方式来编写这个规范,但我无法弄明白。有没有人有任何想法?

(我知道我可以将此服务的测试编写为标准的ES6类,但是我的组件和服务使用Http响应模拟角度的东西得到了相同的场景。)

这是我的spec文件:

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: 'dave@gmail.com'
        };
      }
    };

    /**
     * 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 ... */

  });

});

1 个答案:

答案 0 :(得分:4)

可能是

的一些变种
function setupUserTestbed() {
    beforeEach(() => {
      TestBed.configureTestingModule({...});
    });

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

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

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

如果顶级describe块有beforeEach阻止,则可以确定它会影响嵌套describe块中的规范。如果describe块是兄弟姐妹,则应将常见行为移至顶级describe。如果兄弟describe块没有顶级describe,则应该创建它。

在已发布的代码中,顶级describe('User service - ', () => { ... })beforeEachTestBed.configureTestingModuleTestBed.resetTestingModule(应在afterEach中执行)和{{1} }}。没有必要在嵌套的inject块中复制它们。

describe类的配方与在规格之间交替的任何模拟相同。它应该是MockRestService / let变量:

var

这种模式可能有很多变化。类本身可能是常量,但describe(... let MockRestService = class MockRestService { ... }; beforeEach(() => { Testbed... }); describe(... MockRestService = class MockRestService { ... }; beforeEach(inject(...)); getUser属性可以交替使用:

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之前重新分配upsertUserSpyTestbed(这可能是实例化inject类的地方)。