Skip to content

Instantly share code, notes, and snippets.

@krimple
Last active June 7, 2018 15:37
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save krimple/18393de524d99b142a7b to your computer and use it in GitHub Desktop.
Save krimple/18393de524d99b142a7b to your computer and use it in GitHub Desktop.
Test and class under test for Http mocking - Angular 2 beta 1

This snippet is a working example of a test against the Http service in Angular 2.0.

It is a very simple test, and provides an example of how to:

  • Provide the right wiring to the test injector
  • Inject the fake XHRBackend (i.e. MockBackend)
  • Define a potential request
  • Run the request in the framework
  • Set expectations on the result

The biggest "Gotcha" is if you accidentally (as I did) provide MockBackend, thinking that the injector must create this before you request it. You would be in error if you did inject([MockBackend], mockBackend) because it doesn't actually wire up the right components.

See https://github.com/krimple/angular2-webpack-demo-routing-and-http for the sample.

import {BlogService} from "../../../src/app/services/blog-service";
import {
describe,
expect,
beforeEach,
it,
inject,
injectAsync,
beforeEachProviders
} from 'angular2/testing';
import {Headers, HTTP_PROVIDERS, BaseRequestOptions, XHRBackend, Response} from 'angular2/http';
import {provide} from 'angular2/core';
import {MockBackend} from 'angular2/http/testing';
import {BlogEntry} from '../../../src/app/domain/blog-entry';
import {MockConnection} from 'angular2/src/http/backends/mock_backend';
import {ResponseOptions} from 'angular2/http';
import {Injector} from 'angular2/core';
describe('Blog Service', () => {
// All heed this block - it is required so that the test injector
// is properly set up. Without doing this, you won't get the
// fake backend injected into Http.
// Also, you need to inject MockBackend as a provider before you wire
// it to replace XHRBackend with the provide function! So this is all
// extremely important to set up right.
beforeEachProviders(() => {
return [
HTTP_PROVIDERS,
provide(XHRBackend, {useClass: MockBackend}),
BlogService
];
});
it('should get blogs', inject([XHRBackend, BlogService], (mockBackend, blogService) => {
mockBackend.connections.subscribe(
(connection: MockConnection) => {
connection.mockRespond(new Response(
new ResponseOptions({
body: [
{
id: 26,
contentRendered: "<p><b>Hi there</b></p>",
contentMarkdown: "*Hi there*"
}]
}
)));
});
blogService.getBlogs().subscribe((blogs: BlogEntry[]) => {
expect(blogs.length).toBe(1);
expect(blogs[0].id).toBe(26);
});
}));
it('should get blogs async', injectAsync([XHRBackend, BlogService], (mockBackend, blogService) => {
return new Promise((pass, fail) => {
mockBackend.connections.subscribe(
(connection: MockConnection) => {
connection.mockRespond(new Response(
new ResponseOptions({
body: [
{
id: 26,
contentRendered: "<p><b>Hi there</b></p>",
contentMarkdown: "*Hi there*"
}]
}
)));
});
blogService.getBlogs().subscribe(
(data) => {
expect(data.length).toBe(1);
expect(data[0].id).toBe(26);
expect(data[0].contentMarkdown).toBe('*Hi there*');
});
});
}), 3000);
it('should save updates to an existing blog entry',
injectAsync([XHRBackend, BlogService], (mockBackend, blogService) => {
return new Promise((resolve, reject) => {
mockBackend.connections.subscribe(connection => {
connection.mockRespond(new ResponseOptions({status: 200}));
});
let data: BlogEntry = new BlogEntry("Blog Entry", "<p><b>Hi</b></p>", "*Hi*", 10);
blogService.saveBlog(data).subscribe(
(successResult) => {
expect(successResult).toBeDefined( );
expect(successResult.status).toBe(200);
});
});
}), 300);
});
import {Headers, RequestOptions, Response} from 'angular2/http';
import {Http} from 'angular2/http';
import {Observable} from 'rxjs/Observable';
import {Inject} from 'angular2/core';
import {Injectable} from 'angular2/core';
import {BlogEntry} from '../domain/blog-entry';
import 'rxjs/add/operator/map';
@Injectable()
export class BlogService {
opts: RequestOptions;
constructor(private http: Http) {
var headers: Headers = new Headers();
headers.append('content-type', 'application/json; charset=utf-8');
this.opts = new RequestOptions();
this.opts.headers = headers;
}
getBlogs(): Observable<any> {
return this.http.get('/api/blogs')
.map((res: Response) => { return BlogEntry.asBlogEntries(res.json()); });
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment