Reputation: 1218
I'm currently getting an error that says "can't read property 'get' of null" which is because I'm passing in null as my first argument to the FirmService constructor in my beforeEach in my spec file...what is the best way to mock or pass in http to my service here?
@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;
}
}
}
Here is my unit test for the above service:
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);
};
}
}
}
Upvotes: 0
Views: 130
Reputation: 8990
you can try something using MockBackend and MockConnection from angular's http/testing library:
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 }
]
});
};
then before each test:
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);
});
sample test using an Array of Items as result:
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);
}
Upvotes: 1