First: I'm aware that Angular2 is in alpha and changing frequently.
I'm working with Angular2. There is an injectable service with http dependency that I'd like to test using a mock backend. The service works when the app starts but I'm having no luck writing the test and getting the mock backend to respond. Any insight, is there something obvious in the test setup or implementation that I'm missing?
service/core.ts:
import { Injectable } from 'angular2/angular2';
import { Http } from 'angular2/http';
@Injectable()
export class CoreService {
constructor(public http:Http) {}
getStatus() {
return this.http.get('/api/status')
.toRx()
.map(res => res.json());
}
}
service/core_spec.ts:
import {
AsyncTestCompleter,
TestComponentBuilder,
By,
beforeEach,
ddescribe,
describe,
el,
expect,
iit,
inject,
it,
xit
} from 'angular2/test';
import { MockBackend, MockConnection, BaseRequestOptions, Http, Response } from 'angular2/http';
import { Injector, bind } from 'angular2/angular2';
import { ObservableWrapper } from 'angular2/src/core/facade/async'
import { CoreService } from 'public/services/core'
export function main() {
describe('public/services/core', () => {
let backend: MockBackend;
let response: Response;
let coreService: CoreService;
let injector: Injector;
afterEach(() => backend.verifyNoPendingRequests());
it('should get status', inject([AsyncTestCompleter], (async) => {
injector = Injector.resolveAndCreate([
BaseRequestOptions,
MockBackend,
bind(Http).toFactory((backend, options) => {
return new Http(backend, options)
}, [MockBackend, BaseRequestOptions]),
bind(CoreService).toFactory((http) => {
return new CoreService(http);
}, [Http])
]);
backend = injector.get(MockBackend);
coreService = injector.get(CoreService);
response = new Response('foo');
ObservableWrapper.subscribe<MockConnection>(backend.connections, c => {
expect(c.request.url).toBe('/api/status');
c.mockRespond(response);
});
// attempt #1: fails because res argument is undefined
coreService.getStatus().subscribe(res => {
expect(res).toBe('');
async.done();
});
// attempt #2: fails because emitter.observer is not a function
ObservableWrapper.subscribe(coreService.getStatus(), res => {
expect(res).toBe('');
async.done();
});
}));
});
}
Related: https://github.com/angular/angular/issues/3502 https://github.com/angular/angular/issues/3530
I just found this topic while looking for testing tips but I can't see a direct answer to that so...
This one is based on Angular RC.1
Testing service with Mock Backend
Let's say your service is:
Test to the service above will look like this:
What you really have to look at there is to have proper mocking in
beforeEachProviders
. Test itself is quite simple and ends up with subscribing to the service method.Note: Don't forget to set base providers first:
Since asking this question we did upgrade to Angular2 RC 1. Our imports look like Wojciech Kwiatek's (thank you for your answer!) but our testing strategy is slightly different. We wanted to assert on the request as well as the response. Instead of using
beforeEachProviders()
, we usedbeforeEach()
where we create our own injector and save a reference to the service-under-test and mock backend. This allows us to assert on the request and manage the response inside the test, and it lets us use theverifyNoPendingRequests()
method after each test.Edit: Plunker updated to RC2. https://plnkr.co/edit/nlvUZVhKEr8d2mz8KQah?p=preview