Skip to content

Instantly share code, notes, and snippets.

@wkwiatek
Last active December 17, 2021 01:52
Show Gist options
  • Star 83 You must be signed in to star a gist
  • Fork 26 You must be signed in to fork a gist
  • Save wkwiatek/e8a4a9d92abc4739f04f5abddd3de8a7 to your computer and use it in GitHub Desktop.
Save wkwiatek/e8a4a9d92abc4739f04f5abddd3de8a7 to your computer and use it in GitHub Desktop.
Angular 2 test snippets for Angular final version. Codebase for https://developers.livechatinc.com/blog/category/programming/angular-2/
// App
import { Component } from '@angular/core';
@Component({
selector: 'app',
template: '<span>{{ sayHello() }}</span>',
})
export class App {
public name: string = 'John';
sayHello(): string {
return `Hello ${this.name}`;
}
}
// App tests
describe('App', () => {
beforeEach(() => {
this.app = new App();
});
it('should have name property', () => {
expect(this.app.name).toBe('John');
});
it('should say hello with name property', () => {
expect(this.app.sayHello()).toBe('Hello John');
});
});
// App
import { Component, Input } from '@angular/core';
@Component({
selector: 'list',
template: '<span *ngFor="let user of users">{{ user }}</span>',
})
export class ListComponent {
@Input() public users: Array<string> = [];
}
// App tests
import { async, inject, TestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
describe('ListComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [ListComponent]
});
this.fixture = TestBed.createComponent(ListComponent);
});
it('should render list', async(() => {
const element = this.fixture.nativeElement;
this.fixture.componentInstance.users = ['John'];
this.fixture.detectChanges();
expect(element.querySelectorAll('span').length).toBe(1);
}));
});
// App DI
class UserService {
public users: Array<string> = ['John'];
}
@Component({
selector: 'list',
template: '<span *ngFor="let user of users">{{ user }}</span>',
})
class ListComponentBootstrapDI {
private users: Array<string> = [];
constructor(userService: UserService) {
this.users = userService.users;
}
}
class MockUserService {
public users: Array<string> = ['John', 'Steve'];
}
describe('ListComponent DI', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [ListComponentBootstrapDI],
providers: [{ provide: UserService, useClass: MockUserService }],
});
this.fixture = TestBed.createComponent(ListComponentBootstrapDI);
});
it('should render list', async(() => {
const element = this.fixture.nativeElement;
this.fixture.detectChanges();
expect(element.querySelectorAll('span').length).toBe(2);
}));
});
// App DI for Component
@Component({
selector: 'list',
template: '<span *ngFor="let user of users">{{ user }}</span>',
providers: [UserService],
})
class ListComponentComponentDI {
private users: Array<string> = [];
constructor(userService: UserService) {
this.users = userService.users;
}
}
// App DI for Component tests
describe('ListComponent DI Component', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [ListComponentBootstrapDI],
});
this.fixture = TestBed
.overrideComponent(ListComponentBootstrapDI, {
set: {
providers: [{ provide: UserService, useClass: MockUserService }],
},
})
.createComponent(ListComponentBootstrapDI);
});
it('should render list', async(() => {
const element = this.fixture.nativeElement;
this.fixture.detectChanges();
expect(element.querySelectorAll('span').length).toBe(2);
}));
});
// App
class TestService {
public name: string = 'Injected Service';
}
// App tests
import { inject, TestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
describe('TestService', () => {
beforeEach(() => {
this.testService = new TestService();
});
it('should have name property set', () => {
expect(this.testService.name).toBe('Injected Service');
});
});
describe('TestService Injected', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [TestService],
});
});
it('should have name property set', inject([TestService], (testService: TestService) => {
expect(testService.name).toBe('Injected Service');
}));
});
class MockTestService {
public mockName: string = 'Mocked Service';
}
describe('TestService Mocked', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [{ provide: TestService, useClass: MockTestService }],
});
});
it('should have name property set', inject([TestService], (testService: TestService) => {
expect(testService.mockName).toBe('Mocked Service');
}));
});
class MockTestServiceInherited extends TestService {
public sayHello(): string {
return this.name;
}
}
describe('TestService Mocked Inherited', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [{ provide: TestService, useClass: MockTestServiceInherited }],
});
});
it('should say hello with name', inject([TestService], (testService: TestService) => {
expect(testService.sayHello()).toBe('Injected Service');
}));
});
// App
import { Injectable } from '@angular/core';
import { Http } from '@angular/http';
@Injectable()
export class TestService {
constructor(private http: Http) {}
getUsers() {
return this.http.get('http://foo.bar');
}
}
// App tests
import { inject, TestBed } from '@angular/core/testing';
import { BaseRequestOptions, Response, ResponseOptions } from '@angular/http';
import { MockBackend, MockConnection } from '@angular/http/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
describe('Http', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [
TestService,
BaseRequestOptions,
MockBackend,
{
provide: Http,
useFactory: (backend: MockBackend, defaultOptions: BaseRequestOptions) => {
return new Http(backend, defaultOptions);
},
deps: [MockBackend, BaseRequestOptions],
},
],
});
});
beforeEach(inject([MockBackend], (backend: MockBackend) => {
const baseResponse = new Response(new ResponseOptions({ body: 'got response' }));
backend.connections.subscribe((c: MockConnection) => c.mockRespond(baseResponse));
}));
it('should return response when subscribed to getUsers', inject([TestService], (testService: TestService) => {
testService.getUsers().subscribe((res: Response) => {
expect(res.text()).toBe('got response');
});
}));
})
// App
import { Component } from '@angular/core';
import { Routes } from '@angular/router';
@Component({
selector: 'app',
template: `<router-outlet></router-outlet>`
})
class AppComponent {}
// App tests
import { async, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
TestBed.initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
describe('AppComponent', () => {
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [AppComponent],
imports: [RouterTestingModule]
});
});
it('should be able to test', async(() => {
const fixture = TestBed.createComponent(AppComponent);
fixture.whenStable().then(() => {
expect(true).toBe(true);
});
}));
});
@cdcooksey
Copy link

Thank you for updating this to reflect the latest changes!

@Ajeey
Copy link

Ajeey commented Jul 9, 2016

What about testing for HTTP error codes like 202, 404 or 503?

@osadan
Copy link

osadan commented Jul 25, 2016

tnx man you helped me a lot .
but why I can not find @angular/router/testing

@vespertilian
Copy link

@osadan seems to be in RC5

@Serginho
Copy link

Pretty nice gist! Thanks. The lack of docs among releases is obvious, so this is cool!

@hongbo-miao
Copy link

hongbo-miao commented Sep 7, 2016

thank you for providing these gists!

@anand-ma
Copy link

anand-ma commented Sep 9, 2016

Does this holds good for RC.6 ?, Upto what version is this code snippets valid?

@wkwiatek
Copy link
Author

I was able to update it to the final version of Angular 2. Enjoy!

@iamyojimbo
Copy link

Thanks for this!

@JohannesHoppe
Copy link

JohannesHoppe commented Dec 14, 2016

https://gist.github.com/wkwiatek/e8a4a9d92abc4739f04f5abddd3de8a7#file-app-3-http-spec-ts-L49

Yay! First HTTP example that I see that does not uses uses async() or fackeAsyc() / tick().
Does somebody knows since when this is not required any more? Code seems to run fully synchronous anyway...

@piq9117
Copy link

piq9117 commented Jan 4, 2017

awesome! thank you!

@sp-andres-gutierrez
Copy link

Hi, thanks for the gist! I've a question.

How can I change just one provider. In my case I've a component that have a resolver that returns data from 2 API calls. The data of this resolver is on ActivatedRoute provider. I want to have multiple test cases with different data. How could I override just ActivatedRoute?

I'm looking into overrideComponent this way:

// getDefaultProviders return an Array with common providers
        fixture = TestBed
          .configureTestingModule({
            imports: [ HttpModule, SchedulesModule ],
            providers: [ ...getDefaultProviders() ]
          })
          .overrideComponent(MyComponent, {
            set: {
              providers: [
                {
                  provide: ActivatedRoute,
                  useValue: { snapshot: { data: { myData: 'Something here different in each scenario' } } },
                },
              ]
            }
          })
          .createComponent(MyComponent);

It's a good idea to have multiple configureTestingModule in the same file?

@gviligvili
Copy link

Thank you !

@lortiz211
Copy link

lortiz211 commented Mar 1, 2017

@Ajeey, You can do something like this

beforeEach(() => {
        TestBed.configureTestingModule({
            imports: [HttpModule],
            declarations: [Component],
            providers: [{provide: XHRBackend, useClass: MockBackend}]
        }).compileComponents();

        fixture = TestBed.createComponent(SendEmailComponent);
        component = fixture.componentInstance;
    });
   // and then to test it you do these

it("should do somthing", async(inject([XHRBackend], (be: MockBackend) => {
    be.connections.subscribe((c: MockConnection) => c.mockError(error));

   // and you execute the function that makes the request
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment