Skip to content
This repository was archived by the owner on Sep 21, 2018. It is now read-only.

Commit 9662847

Browse files
vespertiliankrjordan
authored andcommitted
Added tests for the effects and the books reducer (#106)
1 parent ba26f4f commit 9662847

File tree

6 files changed

+400
-2
lines changed

6 files changed

+400
-2
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
.settings/
1717

1818
# IDE - VSCode
19+
.vscode
1920
.vscode/*
2021
!.vscode/settings.json
2122
!.vscode/tasks.json

src/app/effects/book.spec.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { EffectsTestingModule, EffectsRunner } from '@ngrx/effects/testing';
2+
import { TestBed, fakeAsync, tick } from '@angular/core/testing';
3+
import { BookEffects } from './book';
4+
import { GoogleBooksService } from '../services/google-books';
5+
import { Observable } from 'rxjs/Observable';
6+
import 'rxjs/add/Observable/of'
7+
import 'rxjs/add/Observable/throw'
8+
import { SearchAction, SearchCompleteAction } from '../actions/book';
9+
import { Book } from '../models/book';
10+
11+
describe('BookEffects', () => {
12+
beforeEach(() => TestBed.configureTestingModule({
13+
imports: [
14+
EffectsTestingModule
15+
],
16+
providers: [
17+
BookEffects,
18+
{
19+
provide: GoogleBooksService,
20+
useValue: jasmine.createSpyObj('googleBooksService', ['searchBooks'])
21+
}
22+
]
23+
}));
24+
25+
function setup(params?: {searchBooksReturnValue: any}) {
26+
const googleBooksService = TestBed.get(GoogleBooksService);
27+
if (params) googleBooksService.searchBooks.and.returnValue(params.searchBooksReturnValue);
28+
29+
return {
30+
runner: TestBed.get(EffectsRunner),
31+
bookEffects: TestBed.get(BookEffects)
32+
};
33+
}
34+
35+
describe('search$', () => {
36+
it('should return a new book.SearchCompleteAction, with the books, on success, after the de-bounce', fakeAsync(() => {
37+
const book1 = {id: '111', volumeInfo: {}} as Book;
38+
const book2 = {id: '222', volumeInfo: {}} as Book;
39+
const books = [book1, book2];
40+
41+
const {runner, bookEffects} = setup({searchBooksReturnValue: Observable.of(books)});
42+
43+
const expectedResult = new SearchCompleteAction(books);
44+
runner.queue(new SearchAction('query'));
45+
46+
let result = null;
47+
bookEffects.search$.subscribe(_result => result = _result);
48+
tick(299); // test de-bounce
49+
expect(result).toBe(null);
50+
tick(300);
51+
expect(result).toEqual(expectedResult);
52+
}));
53+
54+
it('should return a new book.SearchCompleteAction, with an empty array, if the books service throws', fakeAsync(() => {
55+
const {runner, bookEffects} = setup({searchBooksReturnValue: Observable.throw(new Error())});
56+
57+
const expectedResult = new SearchCompleteAction([]);
58+
runner.queue(new SearchAction('query'));
59+
60+
let result = null;
61+
bookEffects.search$.subscribe(_result => result = _result);
62+
tick(299); // test de-bounce
63+
expect(result).toBe(null);
64+
tick(300);
65+
expect(result).toEqual(expectedResult);
66+
}));
67+
68+
it(`should not do anything if the query is an empty string`, fakeAsync(() => {
69+
const {runner, bookEffects} = setup();
70+
71+
runner.queue(new SearchAction(''));
72+
let result = null;
73+
bookEffects.search$.subscribe({
74+
next: () => result = false,
75+
complete: () => result = false,
76+
error: () => result = false
77+
});
78+
79+
tick(300);
80+
expect(result).toBe(null);
81+
}));
82+
83+
});
84+
});
85+

src/app/effects/collection.spec.ts

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
import { EffectsTestingModule, EffectsRunner } from '@ngrx/effects/testing';
2+
import { TestBed } from '@angular/core/testing';
3+
import { CollectionEffects } from './collection';
4+
import { Database } from '@ngrx/db';
5+
import { Book } from '../models/book';
6+
import * as collection from '../actions/collection';
7+
import { Observable } from 'rxjs/Observable';
8+
import 'rxjs/add/Observable/of'
9+
import 'rxjs/add/Observable/throw'
10+
11+
describe('CollectionEffects', () => {
12+
beforeEach(() => TestBed.configureTestingModule({
13+
imports: [
14+
EffectsTestingModule
15+
],
16+
providers: [
17+
CollectionEffects,
18+
{
19+
provide: Database,
20+
useValue: jasmine.createSpyObj('database', ['open', 'query', 'insert', 'executeWrite'])
21+
}
22+
]
23+
}));
24+
25+
function setup() {
26+
return {
27+
db: TestBed.get(Database),
28+
runner: TestBed.get(EffectsRunner),
29+
collectionEffects: TestBed.get(CollectionEffects)
30+
};
31+
}
32+
33+
describe('openDB$', () => {
34+
it('should call db.open when initially subscribed to', () => {
35+
const {db, collectionEffects} = setup();
36+
collectionEffects.openDB$.subscribe();
37+
expect(db.open).toHaveBeenCalledWith('books_app');
38+
});
39+
});
40+
41+
describe('loadCollection$', () => {
42+
it('should return a collection.LoadSuccessAction, with the books, on success', () => {
43+
const book1 = {id: '111', volumeInfo: {}} as Book;
44+
const book2 = {id: '222', volumeInfo: {}} as Book;
45+
46+
const {db, runner, collectionEffects} = setup();
47+
48+
const booksObservable = Observable.of(book1, book2);
49+
db.query.and.returnValue(booksObservable);
50+
51+
const expectedResult = new collection.LoadSuccessAction([book1, book2]);
52+
53+
runner.queue(new collection.LoadAction());
54+
55+
collectionEffects.loadCollection$.subscribe(result => {
56+
expect(result).toEqual(expectedResult);
57+
});
58+
});
59+
60+
it('should return a collection.LoadFailAction, if the query throws', () => {
61+
const {db, runner, collectionEffects} = setup();
62+
63+
const error = new Error('msg');
64+
db.query.and.returnValue(Observable.throw(error));
65+
66+
const expectedResult = new collection.LoadFailAction(error);
67+
68+
runner.queue(new collection.LoadAction());
69+
70+
collectionEffects.loadCollection$.subscribe(result => {
71+
expect(result).toEqual(expectedResult);
72+
});
73+
});
74+
});
75+
76+
describe('addBookToCollection$', () => {
77+
it('should return a collection.AddBookSuccessAction, with the book, on success', () => {
78+
const book = {id: '111', volumeInfo: {}} as Book;
79+
80+
const {db, runner, collectionEffects} = setup();
81+
db.insert.and.returnValue(Observable.of({}));
82+
83+
const expectedResult = new collection.AddBookSuccessAction(book);
84+
85+
runner.queue(new collection.AddBookAction(book));
86+
87+
collectionEffects.addBookToCollection$.subscribe(result => {
88+
expect(result).toEqual(expectedResult);
89+
expect(db.insert).toHaveBeenCalledWith('books', [book]);
90+
});
91+
});
92+
93+
it('should return a collection.AddBookFailAction, with the book, when the db insert throws', () => {
94+
const book = {id: '111', volumeInfo: {}} as Book;
95+
96+
const {db, runner, collectionEffects} = setup();
97+
db.insert.and.returnValue(Observable.throw(new Error()));
98+
99+
const expectedResult = new collection.AddBookFailAction(book);
100+
101+
runner.queue(new collection.AddBookAction(book));
102+
103+
collectionEffects.addBookToCollection$.subscribe(result => {
104+
expect(result).toEqual(expectedResult);
105+
expect(db.insert).toHaveBeenCalledWith('books', [book]);
106+
});
107+
});
108+
109+
describe('removeBookFromCollection$', () => {
110+
it('should return a collection.RemoveBookSuccessAction, with the book, on success', () => {
111+
const book = {id: '111', volumeInfo: {}} as Book;
112+
113+
const {db, runner, collectionEffects} = setup();
114+
db.executeWrite.and.returnValue(Observable.of({}));
115+
116+
const expectedResult = new collection.RemoveBookSuccessAction(book);
117+
118+
runner.queue(new collection.RemoveBookAction(book));
119+
120+
collectionEffects.removeBookFromCollection$.subscribe(result => {
121+
expect(result).toEqual(expectedResult);
122+
expect(db.executeWrite).toHaveBeenCalledWith('books', 'delete', ['111']);
123+
});
124+
});
125+
126+
it('should return a collection.RemoveBookFailAction, with the book, when the db insert throws', () => {
127+
const book = {id: '111', volumeInfo: {}} as Book;
128+
129+
const {db, runner, collectionEffects} = setup();
130+
db.executeWrite.and.returnValue(Observable.throw(new Error()));
131+
132+
const expectedResult = new collection.RemoveBookFailAction(book);
133+
134+
runner.queue(new collection.RemoveBookAction(book));
135+
136+
collectionEffects.removeBookFromCollection$.subscribe(result => {
137+
expect(result).toEqual(expectedResult);
138+
expect(db.executeWrite).toHaveBeenCalledWith('books', 'delete', ['111']);
139+
});
140+
});
141+
});
142+
});
143+
});

0 commit comments

Comments
 (0)