【问题标题】:How to testing a service in Angular 7如何在 Angular 7 中测试服务
【发布时间】:2019-04-12 09:13:24
【问题描述】:

我想测试从我的服务收到的数据。 我阅读了角度文档并遵循了 observable 示例,但是当我订阅 observable 时我没有收到任何数据。 Console.log() 在订阅中不起作用。

服务正常运行,并在真实环境中获取正确的数据。

我尝试使用 async 和 doneFn,但它们都没有工作,它们都超时了。

服务文件

export class BackService {

  URL = '********'; // I removed url for security.

  constructor(private httpClient: HttpClient) { }

  getAllForms(): Observable<Array<object>> {
    return this.httpClient.get<Array<object>>(`${this.URL}/allForms`);
  }

  getFormById(formId): Observable<Array<object>> {
    return this.httpClient.get<Array<object>>(`${this.URL}/form/${formId}`);
  }
}

测试服务文件

import { TestBed } from '@angular/core/testing';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { BackService } from './back.service';


describe('BackService', () => {
  let httpMock: HttpTestingController;
  let backService: BackService;
  beforeEach(() => {
    TestBed.configureTestingModule({
    imports: [ HttpClientTestingModule ],
    providers: [BackService]
    });
    backService = TestBed.get(BackService);
    httpMock = TestBed.get(HttpTestingController);
  });
  it('should be created', () => {
    expect(backService).toBeTruthy();
  });
  describe('Methods', () => {
    describe('All Forms', () => {
      it('should use GET method', () => {
        backService.getAllForms().subscribe();
        const req = httpMock.expectOne(`${backService.URL}/allForms`);
        expect(req.request.method).toBe('GET');
      });
      it('should use the right url', () => {
        backService.getAllForms().subscribe();
        const req = httpMock.expectOne(`${backService.URL}/allForms`);
        expect(req.request.url).toBe(`${backService.URL}/allForms`);
      });
      it('should return the right data', () => {
        const mockData = [{'_id': 435345345, '_type': 'window'}]
        backService.getAllForms().subscribe(data => {
          expect(data).toEqual(mockData);
        });
      });
    });
  });

【问题讨论】:

  • 你遇到了什么问题?

标签: javascript angular unit-testing


【解决方案1】:

前 2 个测试看起来没问题,要让第三个测试接收您可以测试的数据,您必须通过使用您希望 httpClient 返回的必要对象调用其 flush() 方法来触发该“httpMock”。

这应该适用于第三次测试:

it('should return the right data', () => {
    const mockData = [{'_id': 435345345, '_type': 'window'}]
    backService.getAllForms().subscribe(data => {
      expect(data).toEqual(mockData);
    });
    const req = httpMock.expectOne(`${backService.URL}/allForms`);
    req.flush(mockData);
});

【讨论】:

  • 另外我建议对一个端点调用使用一个测试 - 一个测试可以包括“expect(req.request.method).toBe('GET');”方法断言以及第三次测试中的数据断言,这就是不需要第一次测试的原因。也不需要第二次测试,因为在我的示例 url 中已经在数据模拟期间测试过
  • 它失败 BackService › 方法 › 所有表单 › 应该返回正确的数据 期望一个匹配请求的条件“匹配 URL:*****,找不到。
  • 您是否尝试在测试底部声明 req 变量?我在最后一分钟更新了代码 sn-p,因为我得到了同样的错误
  • 是的,它工作正常。非常感谢您的帮助 Andrius
【解决方案2】:

我们进行契约测试是因为您必须模拟很多对我们来说并不真实的东西。

示例

 import {PactWeb} from '@pact-foundation/pact-web';

    describe('FooService', () => {
    let provider: PactWeb;

      beforeAll(async () => {
        await provider.addInteraction({
                    state: 'I have an foo',
                    uponReceiving: 'a request to create an bar',
                    withRequest: {
                      method: 'POST',
                      path: '/url/bars',
                      body: {
                        foo: '123456',
                        bar: 'abcd'
                      }
                    },
                    willRespondWith: {
                      status: 200,
                      headers: {'Content-Type': 'application/json'},
                      body: {
                        foo: '123456',
                        bar: 'abcd'
                      }
                    }
                  });
               });

            it('should create one bar and respond with that bar', async () => {
              const service: FooService = TestBed.get(FooService);
              (service as any).apiBasePath = provider.mockService.baseUrl + 'url';
              const result = await service.createBar({
                        foo: '123456',
                        bar: 'abcd'
              }).toPromise();

              expect(result.id).toEqual('some-random-uuid');

            });

    afterAll(function (done) {
      provider.finalize()
        .then(function () {
          done();
        }, function (err) {
          done.fail(err);
        });
    });
        });

我假设您有一个要测试的名为“createBar”的服务。

只是为了知道你在做什么,所以它是提供者的状态。他有一个foo。在收到请求后,他应该创建一个酒吧

withRequest 显示请求的外观

willRespondWith 显示响应。

【讨论】:

    【解决方案3】:

    你能改用 MockBackend 吗?

    import { TestBed, inject } from "@angular/core/testing";
    import {
      HttpModule,
      Http,
      Response,
      ResponseOptions,
      XHRBackend
    } from "@angular/http";
    import { MockBackend } from "@angular/http/testing";
    import { BackService } from "./back.service";
    
    describe("BackService", () => {
      beforeEach(() => {
        TestBed.configureTestingModule({
          imports: [HttpModule],
          providers: [BackService, { provide: XHRBackend, useClass: MockBackend }]
        });
      });
      describe("getAllForms()", () => {
        it("should return an Observable<Array<Form>>", inject(
          [BackService, XHRBackend],
          (backService, mockBackend) => {
            const mockResponse = {
              data: [
                { id: 0, form: "Form 0" },
                { id: 1, form: "Form 1" },
                { id: 2, form: "Form 2" },
                { id: 3, form: "Form 3" }
              ]
            };
    
            mockBackend.connections.subscribe(connection => {
              connection.mockRespond(
                new Response(
                  new ResponseOptions({
                    body: JSON.stringify(mockResponse)
                  })
                )
              );
            });
    
            backService.getAllForms().subscribe(forms => {
              expect(forms.length).toBe(4);
              expect(forms[0].form).toEqual("Form 0");
              expect(forms[1].form).toEqual("Form 1");
              expect(forms[2].form).toEqual("Form 2");
              expect(forms[3].form).toEqual("Form 3");
            });
          }
        ));
      });
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-09-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 2023-01-30
      • 2021-09-18
      • 2015-07-07
      相关资源
      最近更新 更多