将HTTP传递给Angular 2服务

时间:2017-06-16 02:44:13

标签: angularjs unit-testing karma-jasmine angular2-services ngrx

我目前收到一条错误,上面写着"无法读取属性' get' of null"这是因为我在我的spec文件中传入null作为我在beforeEach中的FirmService构造函数的第一个参数...在这里模拟或传递http给我的服务的最佳方法是什么?

@Injectable
export class FirmService {
 public stateObservable: Observable<FirmState>;

 constructor(private: $http: AuthHttp, private store: Store<FirmState>) {
    this.stateObservable = this.store.select('firmReducer');

  }

  public getFirms(value?: string) {
     return this.$http.get('/api/firm').map((response: Response) => {
           this.store.dispatch({
               type: firmActions.GET_FIRMS,
               payload: response.json()
            });
            return;
     }
  }
}

以下是我对上述服务的单元测试:

import {Store} from '@ngrx/store';
import {FirmService} from './firm.service'
import {firmActions} from './firm.reducer'
import {FirmState} from './firm.state'
import {HttpModule, Http, Response, ResponseOptions, XHRBackend} from 'angular/http';
import {MockBackend, MockConnection} from '@angular/http/testing';

class MockStore extends Store<FirmState> {
    constructor() {
        super(null, null, null)
    }

    public dispatch () {
         return undefined;
     }
}

describe('firm actions', () => {
     it('getFirms should dispatch the GET_FIRMS action', () => {
          let connection: MockConnection;
          const expectedAction = {
             type: firmActions.GET_FIRMS
             payload: undefined
          }

 const mockBackendResponse = (connection: MockConnection, response: string) => {
  connection.mockRespond(new Response(new ResponseOptions({ body: response })));

      TestBed.configureTestingModule({
           imports: [HttpModule],
           providers: [
               {provide: XHRBackend, useClass: MockBackend}
           ]
       });

    spyOn(mockStore, 'dispatch');
    firmService.getFirms().subscribe(result => {
       expect(mockStore.dispatch).toHaveBeenCalled();
       expect(mockStore.dispatch).toHaveBeenCalledWith(expectedAction);
    };
  }
 }
} 

1 个答案:

答案 0 :(得分:1)

你可以尝试使用angular的http /测试库中的MockBackend和MockConnection:

import { ResponseOptions, Response, XHRBackend, HttpModule } from '@angular/http';
import { MockBackend, MockConnection } from '@angular/http/testing';

const mockBackendResponse = (connection: MockConnection, response: string) => {
  connection.mockRespond(new Response(new ResponseOptions({ body: response })));
};

// test module configuration for each test
const testModuleConfig = () => {
  TestBed.configureTestingModule({
    imports: [
      //.. your required modules for this test,
      HttpModule, RouterTestingModule
    ],
    providers: [
      // required services,
      { provide: XHRBackend, useClass: MockBackend }
    ]
  });
};

然后在每次测试之前:

beforeEach(() => {
      injector = getTestBed();
      backend = <any>injector.get(XHRBackend);
      store = injector.get(Store);
      // sets the connection when someone tries to access the backend with an xhr request
      backend.connections.subscribe((c: MockConnection) => connection = c);

      // construct after setting up connections above
        firmService = injector.get(FirmService);
    });

使用项目数组进行样本测试:

t.it('should search', () => {

let list: Array<Item> = []; // ... your sample mock entity with fields

      observer.subscribe(result => {
        expect(result).toEqual(new SearchedAction(list));
      });

      // mock response after the xhr request (which happens in constructor), otherwise it will be undefined
      let expectedJSON:string = JSON.stringify(list);
      mockBackendResponse(connection, expectedJSON);
}