Javascript 如何在Angular 7中测试服务

Javascript 如何在Angular 7中测试服务,javascript,angular,unit-testing,Javascript,Angular,Unit Testing,我想测试我从服务接收到的数据。 我阅读了angular文档,并遵循了observable示例,但在订阅observable时,我没有收到任何数据。 Console.log()在订阅中不起作用 该服务工作正常,并在真实环境中获得正确的数据 我尝试使用async和doneFn,但它们都不起作用,它们都超时了 服务文件 export class BackService { URL = '********'; // I removed url for security. constructo

我想测试我从服务接收到的数据。 我阅读了angular文档,并遵循了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}`);
  }
}

前两个测试看起来不错,第三个测试要接收您可以测试的数据,您必须通过调用其flush()方法来触发“httpock”,并使用您希望您的httpClient返回的必要对象

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

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);
});

我们做pact测试,因为你不得不嘲笑很多对我们来说不真实的东西

示例

 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 显示请求的外观

将与
显示响应。

您可以改用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");
        });
      }
    ));
  });
});
import{TestBed,inject}来自“@angular/core/testing”;
进口{
HttpModule,
Http,,
答复,,
回应,,
XHRBackend
}从“@angular/http”;
从“@angular/http/testing”导入{MockBackend}”;
从“/back.service”导入{BackService};
描述(“后台服务”,()=>{
在每个之前(()=>{
TestBed.configureTestingModule({
导入:[HttpModule],
提供者:[后台服务,{provide:XHRBackend,useClass:MockBackend}]
});
});
描述(“getAllForms()”,()=>{
它(“应该返回一个可观察的”,注入(
[后台服务,XHRBackend],
(后台服务,模拟后端)=>{
常量mockResponse={
数据:[
{id:0,形式:“形式0”},
{id:1,表格:“表格1”},
{id:2,表格:“表格2”},
{id:3,表格:“表格3”}
]
};
mockBackend.connections.subscribe(连接=>{
连接.mockRespond(
新反应(
新反应({
正文:JSON.stringify(mockResponse)
})
)
);
});
backService.getAllForms().subscribe(表单=>{
期望(形式、长度)toBe(4);
expect(表单[0]。表单).toEqual(“表单0”);
expect(forms[1]。form.toEqual(“form 1”);
expect(forms[2].toEqual(“form 2”);
expect(forms[3].toEqual(“form 3”);
});
}
));
});
});

您面临什么问题?我还建议对一个端点调用使用一个测试-一个测试可以包括“expect(req.request.method).toBe('GET');”方法断言以及第三个测试中的数据断言,这就是为什么不需要第一个测试的原因。第二个测试也不需要,因为在我的示例中,url已经在数据模拟过程中进行了测试。它失败了BackService›Methods›All Forms›应该返回正确的数据,期望一个与条件匹配的请求匹配URL:****,未找到。是否尝试在测试底部声明req变量?我在最后一分钟更新了代码片段,因为我遇到了同样的错误。是的,我知道它工作得很好。非常感谢你的帮助,安德里奥斯
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");
        });
      }
    ));
  });
});