通过模拟Http Post-Angular 5

时间:2018-11-27 06:57:24

标签: angular unit-testing jasmine karma-jasmine

我对单元测试完全陌生,我第一次使用jasmine / karma进行单元测试。我在理解如何通过模拟Http Post实现测试方面遇到了一些问题。我经历了一些解决方案,例如: solution1solution2

但是我在理解它们时仍然遇到了一些问题,并且也遇到了一些错误。

按照solution2,我尝试实现如下:

http.service.ts

 update(id,password,url){

    let content = {
        "username": id,
        "password":password,

     }

     const httpOptions = {
      headers: new HttpHeaders({
        'Content-Type':  'application/json'
      })
    };

     return this.http.post(url,content,httpOptions).subscribe((data:any) => {

        if(data.length){
          return true;
        }
        else{
          return false;
        }
      })

http.service.spec.ts

import { TestBed, inject } from '@angular/core/testing';
import { HttpClientModule } from '@angular/common/http'; 
import { HttpService } from './http.service';
import {HttpModule, XHRBackend,Response,ResponseOptions, Connection} from 
'@angular/http';
import {  of } from 'rxjs';
import { MockBackend } from '@angular/http/testing';

 describe('HttpService', () => {
 let mockbackend, service;
 beforeEach(() => {TestBed.configureTestingModule({
 imports:[HttpClientModule, HttpModule],
 providers:[{
 provide: XHRBackend, useclass: MockBackend
 }]

 })
 });

  beforeEach(inject([ XHRBackend], (_service, 
  _mockbackend) => {
  service = _service;
  mockbackend = _mockbackend;
  }));

  it('post method is successfull',() =>{
  const status = 'success';
  const username = '5555555';
  const password = 'test';
  const currentUserExpected = JSON.stringify({status:status});
  const response = { status : status};
  const responseOptions = new ResponseOptions();
  responseOptions.body = JSON.stringify(response);
  mockbackend.connections.subscribe(connection =>{
  connection.mockRespond(new Response(responseOptions));
  });
  service.update(username,password).subscribe(respond =>{
  expect(respond).toEqual(true)
  })
   })

我收到的错误是这样的:

错误

  

无法读取未定义的属性“连接”

有人可以帮我了解我要去哪里的问题。

我也希望收到任何可以帮助我更好地理解这一点的文档。

1 个答案:

答案 0 :(得分:0)

以下是一个可能有帮助的示例: employee-home.service.ts

"data1,date1,"USERS-1","ff",1"
"data1,date1,"name1","Joe1",1"
"data1,date1,"age","1",1"
"data2,date2,"USERS-2","ff",2"
"data2,date2,"name2","Joe1",2"
"data2,date2,"age","2",2"
"data3,date3,"USERS-3","ff",3"
"data3,date3,"name3","Joe1",3"
"data3,date3,"age","3",3"

然后:employee-home.service.spec.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { Employee } from '../models/employee';
import { USER_PROFILE_API_LOCATION  } from '../../serviceConstants';


@Injectable({
  providedIn: 'root'
})
export class EmployeeHomeService {
  constructor(private http: HttpClient) {}

  retrieveEmployee(): Observable<Employee> {
    return this.http.get<Employee>(USER_PROFILE_API_LOCATION);  
  }

  updateEmployee(employee: Employee): Observable<Employee> {
    return this.http.put<Employee>(USER_PROFILE_API_LOCATION, employee); 
  }
}

helpers:async-observable-helpers.ts

import { asyncData, asyncError } from '@bis-angular/shared-helpers-testing';
import { EmployeeHomeService } from './employee-home.service';
import { Employee } from '../models/employee';
import { HttpErrorResponse } from '@angular/common/http';
import { EMPLOYEE } from '../../../fixtures/employee-fixture';

describe('EmployeeHomeService', () => {
  describe('retrieveEmployee function', () => {
     let httpClientSpyGet: { get: jasmine.Spy };
     let employeeHomeServiceGet: EmployeeHomeService;

    beforeEach(() => {
       httpClientSpyGet = jasmine.createSpyObj('HttpClient', ['get']);
       employeeHomeServiceGet = new 
EmployeeHomeService(<any>httpClientSpyGet);
    });

it('should return expected employee (HttpClient called once)', () => {
  const expectedEmployee: Employee = EMPLOYEE;

  httpClientSpyGet.get.and.returnValue(asyncData(expectedEmployee));

  employeeHomeServiceGet
    .retrieveEmployee()
    .subscribe(employee => expect(employee).toEqual(expectedEmployee, 'expected employee'), fail);
  expect(httpClientSpyGet.get.calls.count()).toBe(1, 'one call');
});

it('should return an error when the server returns an error', () => {
  const errorResponse = new HttpErrorResponse({
    error: 'test error',
    status: 404,
    statusText: 'Not Found'
  });

  httpClientSpyGet.get.and.returnValue(asyncError(errorResponse));

  employeeHomeServiceGet
    .retrieveEmployee()
    .subscribe(
      employee => fail('expected an error, not employee'),
      error => expect(error.error).toContain('test error')
    );
});
   });

  describe('updateEmployee function', () => {
    let httpClientSpyPut: { put: jasmine.Spy };
    let employeeHomeServicePut: EmployeeHomeService;
    const expectedEmployee: Employee = EMPLOYEE;

beforeEach(() => {
  httpClientSpyPut = jasmine.createSpyObj('HttpClient', ['put']);
  employeeHomeServicePut = new EmployeeHomeService(<any>httpClientSpyPut);
});

it('should save employee (HttpClient called once)', () => {
  httpClientSpyPut.put.and.returnValue(asyncData(expectedEmployee));

  employeeHomeServicePut
    .updateEmployee(expectedEmployee)
    .subscribe(employee => expect(employee).toEqual(expectedEmployee, 'expected employee'), fail);
  expect(httpClientSpyPut.put.calls.count()).toBe(1, 'one call');
});

it('should return an error when the server returns an error', () => {
  const errorResponse = new HttpErrorResponse({
    error: 'test error',
    status: 404,
    statusText: 'Not Found'
  });

  httpClientSpyPut.put.and.returnValue(asyncError(errorResponse));

  employeeHomeServicePut
    .updateEmployee(expectedEmployee)
    .subscribe(
      employee => fail('expected an error, not employee'),
      error => expect(error.error).toContain('test error')
    );
});
   });
 });