Google Developer Expert
Angular and Web Technologies
git clone git@github.com:blove/ngrx-testing.git
describe('undefined action', () => {
it('should return the default state', () => {
const action = { type: 'NOOP' } as any;
const result = reducer(undefined, action);
expect(result).toBe(initialState);
});
});
describe('[User] Add User', () => {
it('should toggle loading state', () => {
const action = new AddUser({ user });
const result = reducer(initialState, action);
expect(result).toEqual({
...initialState,
error: undefined,
loading: true
});
});
});
describe('[User] Add User Success', () => {
it('should add a user to state', () => {
const action = new AddUserSuccess({ user });
const result = reducer(initialState, action);
expect(result).toEqual({
...initialState,
entities: {
[user.id]: user
},
ids: [user.id],
loading: false
});
});
});
describe('[User] Add User Fail', () => {
it('should update error in state', () => {
const error = new Error();
const action = new AddUserFail({ error });
const result = reducer(initialState, action);
expect(result).toEqual({
...initialState,
error,
loading: false
});
});
});
describe('[User] Add User Fail', () => {
it('should update error in state', () => {
const error = new Error();
const action = new AddUserFail({ error });
const result = reducer(initialState, action);
expect(result).toEqual({
...initialState,
error,
loading: false
});
});
});
@Effect()
addUser: Observable<Action> = this.actions$
.ofType<AddUser>(UserActionTypes.AddUser)
.pipe(
map(action => action.payload),
exhaustMap(payload => this.userService.addUser(payload.user)),
map(user => new AddUserSuccess({ user: user })),
catchError(error => of(new AddUserFail({ error })))
);
npm i jasmine-marbles -D yarn add jasmine-marbles -D
cold("--a--|")
cold("--a--#")
cold("--a-b--|")
describe('addUser', () => {
it('should return an AddUserSuccess action, with the user, on success', () => {
const user = generateUser();
const action = new AddUser({ user });
const outcome = new AddUserSuccess({ user });
actions.stream = hot('-a', { a: action });
const response = cold('-a|', { a: user });
const expected = cold('--b', { b: outcome });
userService.addUser = jest.fn(() => response);
expect(effects.addUser).toBeObservable(expected);
});
});
describe('addUser', () => {
it('should return an AddUserFail action, with an error, on failure', () => {
const user = generateUser();
const action = new AddUser({ user });
const error = new Error();
const outcome = new AddUserFail({ error });
actions.stream = hot('-a', { a: action });
const response = cold('-#|', {}, error);
const expected = cold('--(b|)', { b: outcome });
userService.addUser = jest.fn(() => response);
expect(effects.addUser).toBeObservable(expected);
});
});
export const selectSelectedUserId = createSelector(
selectUserState,
fromUser.getSelectedUserId
);
export const selectSelectedUser = createSelector(
selectUserEntities,
selectSelectedUserId,
(entities, selectedUserId) => entities && entities[selectedUserId]
);
describe('User selectors', () => {
const users = generateUsers(2);
const entities = {
[users[0].id]: users[0],
[users[1].id]: users[1]
};
const selectedUser = users[0];
it('should return null when entities is falsy', () => {
expect(selectSelectedUser.projector(null, selectedUser.id)).toBe(null);
});
it('should get the retrieve the selected user', () => {
expect(selectSelectedUser.projector(entities, selectedUser.id)).toBe(
selectedUser
);
});
});
describe('ngOnInit', () => {
it('should dispatch SelectUser action for specified id parameter', () => {
const action = new SelectUser({ id: user.id });
const spy = jest.spyOn(store, 'dispatch');
expect(spy).toHaveBeenCalledWith(action);
});
it('should dispatch LoadUser action for specified id parameter', () => {
const action = new LoadUser({ id: user.id });
const spy = jest.spyOn(store, 'dispatch');
expect(spy).toHaveBeenCalledWith(action);
});
});