Skip to content

Instantly share code, notes, and snippets.

@dherges
Last active May 12, 2017 07:23
Show Gist options
  • Save dherges/f018089531fa5904cf80cb2b4a98eb12 to your computer and use it in GitHub Desktop.
Save dherges/f018089531fa5904cf80cb2b4a98eb12 to your computer and use it in GitHub Desktop.
Angular Testing Snippets
import { CommonModule } from '@angular/common';
import { Component, ElementRef, Renderer, ViewChild } from '@angular/core';
import { ComponentFixture, TestBed, TestComponentRenderer, async, inject } from '@angular/core/testing';
import { FooComponent } from './foo.component';
/** Test component hosting an IconComponent */
@Component({template: `<foo></foo>`})
class TestComponent {
@ViewChild(FooComponent)
public tested: FooComponent;
}
/** Creates a TestComponent component with the given template */
const createTestComponent = (template: string): ComponentFixture<TestComponent> => {
return TestBed.overrideComponent(TestComponent, { set: { template } }).createComponent(TestComponent);
}
describe(`FooComponent`, () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
TestComponent,
FooComponent
]
}).compileComponents();
});
it(`should ...`, () => {
const fixture = createTestComponent(`<foo bar="123"></foo>`);
// grabs reference to FooComponent instance
const cmpClass = fixture.componentInstance.tested;
// grabs DOM element of <foo></foo> instance
const cmpElement = fixture.debugElement.query((elem) => elem.name === 'foo');
fixture.detectChanges();
expect(cmpClass.bar).toBe('123');
expect(cmpElement).toBeDefined();
});
});
import { Injector } from '@angular/core';
import { async, inject, getTestBed, TestBed } from '@angular/core/testing';
import { Http, HttpModule, Request, RequestMethod, RequestOptions, Response, ResponseOptions,
URLSearchParams, XHRBackend } from '@angular/http';
import { MockBackend, MockConnection } from '@angular/http/testing';
/** Class to be tested */
export class OAuthTokenRepository {
constructor(
private http: Http
) {}
grantFromRefreshToken(refreshToken: string) {
let body = new URLSearchParams();
body.set(`grant_type`, `refresh_token`);
body.set(`refresh_token`, `${refreshToken}`);
let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
return this.http.post(`oauth/token`, body, { headers });
}
}
describe('OAuthTokenRepository', () => {
let backend: MockBackend;
let injector: Injector;
//setup
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ HttpModule ],
providers: [
{ provide: MockBackend, useClass: MockBackend },
{ provide: XHRBackend, useExisting: MockBackend },
{
provide: OAuthTokenRepository,
useFactory: (http: Http) => new OAuthTokenRepository(http),
deps: [ Http ]
}
]
});
injector = getTestBed();
backend = injector.get(MockBackend);
spyOn(Http.prototype, 'request').and.callThrough();
});
afterEach(() => backend.verifyNoPendingRequests());
it(`should refresh the access token`,
async(inject([ OAuthTokenRepository, MockBackend ], (oauth: OAuthTokenRepository, mockBackend: MockBackend) => {
const token: string = 'foobar123';
// prepare fake response from MockBackend
mockBackend.connections.subscribe((c: MockConnection) => {
// expect the test client to make a well-known request
expect(c.request.url).toBe('oauth/token');
expect(c.request.method).toBe(RequestMethod.Post);
expect(c.request.headers.get('Content-Type')).toBe('application/x-www-form-urlencoded');
// expect(c.request.detectContentType()).toBe(ContentType.FORM); // XX .. ContentType is not exposed to public API
// expect request body to contain form data
expect(c.request.getBody()).toBe(`...`);
// respond to test client with a well-known response
c.mockRespond(new Response(new ResponseOptions({ body: '', status: 204 })));
});
// dispatch the http request that is to be tested
oauth.grantFromRefreshToken(`${token}`)
.subscribe((res: Response) => {
// Observable<Response> should emit the fake response, obviously
expect(res.text()).toBe(``);
expect(res.status).toBe(204);
});
})));
});
import { Injector } from '@angular/core';
import { async, inject, getTestBed, TestBed } from '@angular/core/testing';
import { Http, HttpModule, Request, RequestMethod, RequestOptions, Response, ResponseOptions, XHRBackend } from '@angular/http';
import { MockBackend, MockConnection } from '@angular/http/testing';
describe('FakeHttpResponses', () => {
let backend: MockBackend;
let injector: Injector;
//setup
beforeEach(() => {
TestBed.configureTestingModule({
imports: [ HttpModule ],
providers: [
{ provide: MockBackend, useClass: MockBackend },
{ provide: XHRBackend, useExisting: MockBackend }
]
});
injector = getTestBed();
backend = injector.get(MockBackend);
spyOn(Http.prototype, 'request').and.callThrough();
});
afterEach(() => backend.verifyNoPendingRequests());
it(`should call a http request, verify the request, respond with fake data, and verify the response`,
async(inject([ Http, MockBackend ], (http: Http, mockBackend: MockBackend) => {
// prepare fake response from MockBackend
mockBackend.connections.subscribe((c: MockConnection) => {
// expect the test client to make a well-known request
expect(c.request.url).toBe('https://google.com');
expect(c.request.method).toBe(RequestMethod.Get);
// respond to test client with a well-known response
c.mockRespond(new Response(new ResponseOptions({body: 'This is a fake response'})));
});
// SANITY: we're working with a 'fresh' instance of Http, there should be no other request (e.g. from a previous test)
expect(http.request).not.toHaveBeenCalled(); // (this expectation can be omitted)
// dispatch the http request that is to be tested
http.request(new Request(new RequestOptions({url: 'https://google.com', method: RequestMethod.Get})))
.subscribe((res: Response) => {
// Observable<Response> should emit the fake response, obviously
expect(res.text()).toBe(`This is a fake response`);
// SANITY: we've made our http request, it should have been dispatched by Http
expect(http.request).toHaveBeenCalled(); // (this expectation can be omitted)
});
})));
});
import { TestBed } from '@angular/core/testing';
import { Http, HttpModule } from '@angular/http';
import { FeatureModule } from './feature.module';
import { CustomHttp } from './custom-http.service';
describe(`FeatureModule`, () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HttpModule,
FeatureModule
]
});
});
it(`should not provide any service`, () => {
expect(() => TestBed.get(CustomHttp)).toThrowError(/No provider for/);
});
})
describe(`FeatureModule.forRoot()`, () => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [
HttpModule,
FeatureModule.forRoot()
]
});
});
it(`should provide services`, () => {
expect(TestBed.get(CustomHttp)).toBeTruthy();
});
it(`should provide a single instance for 'CustomHttp' and 'Http' injection tokens`, () => {
const http: Http = TestBed.get(Http);
const customHttp: CustomHttp = TestBed.get(CustomHttp);
expect(http).toBeTruthy();
expect(customHttp).toBeTruthy();
// both should be same instance
expect(http).toBe(customHttp);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment