Unit Testing
Unit testing is easy with NGXS and NGXS Data plugin. A basic test looks like this:
describe('AppState', () => {
@StateRepository()
@State({
name: 'app',
defaults: 'hello world'
})
@Injectable()
class AppState extends NgxsDataRepository<string> {}
it(
'should be correct ensure state from AppState',
ngxsTestingPlatform([AppState], (store: Store, app: AppState) => {
expect(store.snapshot()).toEqual({ app: 'hello world' });
expect(app.getState()).toEqual('hello world');
})
);
});
ngxsTestingPlatform
- This is a testing platform that allows you to fully test the entire lifecycle of NGXS methods.
Example where we testing NGXS Lifecycle
// ..
describe('[TEST]: Abstract ngxs data repository', () => {
let event: string[] = [];
interface Model {
value: number;
}
@StateRepository()
@State({
name: 'a',
defaults: { value: 1 }
})
class A extends NgxsDataRepository<Model> implements NgxsDataDoCheck, NgxsDataAfterReset {
constructor() {
super();
event.push(`create: ${this.name}`);
}
public ngxsOnInit(): void {
event.push(`ngxsOnInit: ${this.name}`);
super.ngxsOnInit();
}
public ngxsOnChanges(change: NgxsSimpleChange): void {
event.push(`ngxsOnChanges: ${this.name} -> ${JSON.stringify(change)}`);
super.ngxsOnChanges();
}
public ngxsAfterBootstrap(): void {
event.push(`ngxsAfterBootstrap: ${this.name}`);
super.ngxsAfterBootstrap();
}
public ngxsDataDoCheck(): void {
event.push(`ngxsDataDoCheck: ${this.name}`);
}
public ngxsDataAfterReset(): void {
event.push(`ngxsDataAfterReset: ${this.name}`);
}
}
@StateRepository()
@State({
name: 'b',
defaults: { value: 1 }
})
@Injectable()
class B extends NgxsImmutableDataRepository<Model> implements NgxsDataDoCheck, NgxsDataAfterReset {
constructor() {
super();
event.push(`create: ${this.name}`);
}
public ngxsOnInit(): void {
event.push(`ngxsOnInit: ${this.name}`);
super.ngxsOnInit();
}
public ngxsOnChanges(change: NgxsSimpleChange): void {
event.push(`ngxsOnChanges: ${this.name} -> ${JSON.stringify(change)}`);
super.ngxsOnChanges();
}
public ngxsAfterBootstrap(): void {
event.push(`ngxsAfterBootstrap: ${this.name}`);
super.ngxsAfterBootstrap();
}
public ngxsDataDoCheck(): void {
event.push(`ngxsDataDoCheck: ${this.name}`);
}
public ngxsDataAfterReset(): void {
event.push(`ngxsDataAfterReset: ${this.name}`);
}
}
beforeEach(() => {
event = [];
});
it(
'should be ngxs data repository',
ngxsTestingPlatform([A], (store: Store, a: A) => {
expect(store.snapshot()).toEqual({ a: { value: 1 } });
expect(a.isInitialised).toEqual(true);
expect(a.isBootstrapped).toEqual(true);
a.state$.subscribe((e: Model) => event.push(`state(${a.name}): set value - ${e.value}`));
expect(a.name).toEqual('a');
a.setState({ value: 2 });
expect(a.getState()).toEqual({ value: 2 });
a.initialState.value = 5; // not affected
a.reset();
expect(a.getState()).toEqual({ value: 1 });
a.setState({ value: 3 });
a.setState({ value: 4 });
a.setState({ value: 5 });
a.reset();
store.reset({ a: { value: 10 } });
expect(a.getState()).toEqual({ value: 10 });
expect(event).toEqual([
'create: a',
'ngxsOnChanges: a -> {"currentValue":{"value":1},"firstChange":true}',
'ngxsOnInit: a',
'ngxsAfterBootstrap: a',
'ngxsDataDoCheck: a',
'state(a): set value - 1',
'ngxsOnChanges: a -> {"previousValue":{"value":1},"currentValue":{"value":2},"firstChange":false}',
'state(a): set value - 2',
'ngxsOnChanges: a -> {"previousValue":{"value":2},"currentValue":{"value":1},"firstChange":false}',
'state(a): set value - 1',
'ngxsDataAfterReset: a',
'ngxsOnChanges: a -> {"previousValue":{"value":1},"currentValue":{"value":3},"firstChange":false}',
'ngxsDataDoCheck: a',
'state(a): set value - 3',
'ngxsOnChanges: a -> {"previousValue":{"value":3},"currentValue":{"value":4},"firstChange":false}',
'state(a): set value - 4',
'ngxsOnChanges: a -> {"previousValue":{"value":4},"currentValue":{"value":5},"firstChange":false}',
'state(a): set value - 5',
'ngxsOnChanges: a -> {"previousValue":{"value":5},"currentValue":{"value":1},"firstChange":false}',
'state(a): set value - 1',
'ngxsDataAfterReset: a',
'state(a): set value - 10'
]);
})
);
it(
'should be ngxs data immutable repository',
ngxsTestingPlatform([B], (store: Store, b: B) => {
expect(b.isInitialised).toEqual(true);
expect(b.isBootstrapped).toEqual(true);
b.state$.subscribe((e: Immutable<Model>) => event.push(`state(${b.name}): set value - ${e.value}`));
expect(b.name).toEqual('b');
b.setState({ value: 2 });
expect(b.getState()).toEqual({ value: 2 });
(b.initialState as any).value = 5; // not affected
b.reset();
expect(b.getState()).toEqual({ value: 1 });
b.setState({ value: 3 });
b.setState({ value: 4 });
b.setState({ value: 5 });
b.reset();
store.reset({ b: { value: 10 } });
expect(b.getState()).toEqual({ value: 10 });
expect(event).toEqual([
'create: b',
'ngxsOnChanges: b -> {"currentValue":{"value":1},"firstChange":true}',
'ngxsOnInit: b',
'ngxsAfterBootstrap: b',
'ngxsDataDoCheck: b',
'state(b): set value - 1',
'ngxsOnChanges: b -> {"previousValue":{"value":1},"currentValue":{"value":2},"firstChange":false}',
'state(b): set value - 2',
'ngxsOnChanges: b -> {"previousValue":{"value":2},"currentValue":{"value":1},"firstChange":false}',
'state(b): set value - 1',
'ngxsDataAfterReset: b',
'ngxsOnChanges: b -> {"previousValue":{"value":1},"currentValue":{"value":3},"firstChange":false}',
'ngxsDataDoCheck: b',
'state(b): set value - 3',
'ngxsOnChanges: b -> {"previousValue":{"value":3},"currentValue":{"value":4},"firstChange":false}',
'state(b): set value - 4',
'ngxsOnChanges: b -> {"previousValue":{"value":4},"currentValue":{"value":5},"firstChange":false}',
'state(b): set value - 5',
'ngxsOnChanges: b -> {"previousValue":{"value":5},"currentValue":{"value":1},"firstChange":false}',
'state(b): set value - 1',
'ngxsDataAfterReset: b',
'state(b): set value - 10'
]);
})
);
});
Last updated