【问题标题】:How to use PactJS with Angular 2/4/5 to tests services如何使用 PactJS 和 Angular 2/4/5 来测试服务
【发布时间】:2017-11-13 13:50:58
【问题描述】:

我正在尝试使用 PactJS 来测试我的一些 Angular 服务。我正在使用:

"@pact-foundation/karma-pact": "^2.1.1",
"pact": "^4.2.1",
"pact-web": "^4.2.1",

我无法让测试成功运行。如果不使用异步,订阅回调永远不会受到影响,如果我确实使用异步,那么 Pact 会失败。这是我的代码:

import { TestBed, async, inject } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { ApiService } from '../index';
import { HttpParams } from '@angular/common/http';
import { Group } from '../../grouping/model';
let Pact = require('pact-web');

describe('ApiService', () => {

  let provider;

  beforeAll((done) => {
    provider = Pact({
      consumer: 'client',
      provider: 'server',
      web: true
    });

    // required for slower CI environments
    setTimeout(done, 2000);

    // Required if run with `singleRun: false`
    provider.removeInteractions();
  });

  afterAll((done) => {
    provider.finalize().then(done, e => done.fail(e));
  });

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        HttpClientTestingModule
      ],
      providers: [
        ApiService
      ]
    });
  }));

  afterEach((done) => {
    provider.verify().then(done, e => done.fail(e));
  });

  describe('Get all Groups', () => {

    beforeAll((done) => {
      provider.addInteraction({
        given: 'groups exist',
        uponReceiving: 'a request to get groups',
        withRequest: {
          method: 'GET',
          path: '/api/groups'
        },
        willRespondWith: {
          status: 200,
          headers: {'Content-Type': 'application/json'},
          body: [{
            id: Pact.Matchers.somethingLike(1),
            name: Pact.Matchers.somethingLike('a group name'),
            disabled: Pact.Matchers.somethingLike(false),
          }]
        }
      }).then(done, e => done.fail(e));
    });

    it('should return all groups from API', (done) => {

      const apiService: ApiService = TestBed.get(ApiService);
      const groups: Group[] = [{
        id: 1,
        name: false,
        disabled: false
      }];

      apiService.getGroups().subscribe((response: Group[]) => {
        expect(response).toEqual(groups);
        done()
      });
    });
  });
});

我得到的错误:

Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.

Failed: Actual interactions do not match expected interactions for mock MockService.

Missing requests:
    GET /api/groups

See standard out/err for details.

我一直在关注这两个项目

https://paucls.wordpress.com/2017/08/04/pact-consumer-driven-contract-implementation-in-angular/

https://github.com/koelec/angular-pact-example

有没有人成功地用 Angular 实现了 PactJS,或者我缺少什么来让它工作?

【问题讨论】:

  • 考虑到Pact是用来mock后端的,为什么要用HttpClientTestingModule而不是HttpClientModule呢?它是一个或另一个。 done.fail 没有为规范指定。永远不要忽视错误,因为它们会导致类似这样的问题。

标签: angular testing pact


【解决方案1】:

您的测试结构看起来不错。验证正在发生的事情的一种方法是查看模拟服务器的日志。该错误消息非常清楚 - 它没有收到预期的请求。

如果 HttpClientTestingModule 实际上没有进行真正的调用,那么 Pact 将失败,因为它期待交互 - 这就是我们确认 Provider 需要遵守的合同细节的方式。如果它被模拟出来,我们就不会收到请求,也无法确认您的代码调用了您期望的代码。

所以。确保您的测试确实进行了真正的 HTTP 调用,并检查它们是否确实以正确的顺序使用正确的详细信息(通过检查日志)访问了 Mock Server。

【讨论】:

    【解决方案2】:

    此处指定的错误具体是因为您的一项测试超时(默认为 10 秒),然后验证因该超时测试而失败。我的建议是查看您自己的代码,特别是 ApiService,因为您的订阅回调似乎永远不会被调用:

    apiService.getGroups().subscribe((response: Group[]) => {
            expect(response).toEqual(groups);
            done()
          });
    

    也许getGroups() 中的某些内容失败并且未被捕获,或者订阅实际上不起作用。无论哪种方式,该函数从未调用过端点(根据验证),并且从未调用过回调,因此从未调用过 done() 以来的超时。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-18
      • 1970-01-01
      • 2016-11-25
      • 1970-01-01
      • 2017-06-03
      • 1970-01-01
      相关资源
      最近更新 更多