如何在 Angular 中对 NGXS 进行单元测试?
How to unit test NGXS in Angular?
我正在尝试为 ngOnIt 中的简单 NGXS 调度事件编写单元测试。我也尝试按照 NGXS 文档进行操作,但没有用。有人可以指导我吗?
charts.component.ts:
import { BarchartState } from './states/barchart-state/barchart.state';
import * as BarchartActions from './states/barchart-state/barchart.actions';
@Component({
selector: 'charts',
templateUrl: './charts.component.html',
styleUrls: ['./charts.component.scss'],
})
export class ChartsComponent implements OnInit {
@Select(BarchartState.simpleChartData) barchartData$: Observable<any>;
@Select(BarchartState.isLoading) barchartIsLoading$: Observable<boolean>;
constructor(private store: Store) { }
ngOnInit(): void {
this.store.dispatch([
new BarchartActions.Fetch(),
]);
}
}
charts.component.spec.ts
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NgxsModule, Store } from '@ngxs/store';
import { ChartsComponent } from './charts.component';
import { BarchartService } from './states/barchart-state/barchart.service';
import { BarchartState } from './states/barchart-state/barchart.state';
import * as BarchartActions from './states/barchart-state/barchart.actions';
describe('ChartsComponent ', () => {
let component: ChartsComponent ;
let fixture: ComponentFixture<ChartsComponent >;
let store: Store;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ChartsComponent ],
imports: [
NgxsModule.forRoot([BarchartState])
],
providers: [
BarchartService
]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ChartsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
store = TestBed.inject(Store);
});
it('should create', () => {
expect(component).toBeTruthy();
});
// I tried doing this but it doesn't work. It gives an error that simpleChartData is undefined
// Can someone please guide what should I write in the test below?
it('it should dispatch barchart fetch action', () => {
store.dispatch(new BarchartActions.Fetch());
const data = store.selectSnapshot(state => state.barchart.simpleChartData);
expect(data).toBe(true);
});
});
barchart.actions.ts
export class Fetch {
static readonly type = '[Barchart] Fetch';
}
任何线索都会有所帮助!谢谢!
我会这样做:
我写了很多评论,所以你可以通过它来理解。
describe('ChartsComponent ', () => {
// add dispatchSpy variable so we will know when it is called
let dispatchSpy: jasmine.Spy;
let component: ChartsComponent ;
let fixture: ComponentFixture<ChartsComponent >;
let store: Store;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ChartsComponent ],
imports: [
NgxsModule.forRoot([BarchartState])
],
providers: [
BarchartService
]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ChartsComponent);
component = fixture.componentInstance;
// get a handle on the store before so we can see when dispatch was called
store = TestBed.inject(Store);
// assign dispatchSpy to when store.dispatch is called
// and put callThrough so when it is actually called, call the actual
// implementation so the store gets notified
dispatchSpy = spyOn(store, 'dispatch').and.callThrough();
// the first fixture.detectChanges() we call is when
// ngOnInit is called. That's why we had to get a handle on the store
// before the first fixture.detectChanges()
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
// I tried doing this but it doesn't work. It gives an error that simpleChartData is undefined
// Can someone please guide what should I write in the test below?
it('it should dispatch barchart fetch action', () => {
// it should be as simple as this
// The first fixture.detectChanges calls ngOnInit for us and we have a
// handle on when store.dispatch is called before ngOnInit
expect(dispatchSpy).toHaveBeenCalledWith([new BarchartActions.Fetch(),]);
});
});
我正在尝试为 ngOnIt 中的简单 NGXS 调度事件编写单元测试。我也尝试按照 NGXS 文档进行操作,但没有用。有人可以指导我吗?
charts.component.ts:
import { BarchartState } from './states/barchart-state/barchart.state';
import * as BarchartActions from './states/barchart-state/barchart.actions';
@Component({
selector: 'charts',
templateUrl: './charts.component.html',
styleUrls: ['./charts.component.scss'],
})
export class ChartsComponent implements OnInit {
@Select(BarchartState.simpleChartData) barchartData$: Observable<any>;
@Select(BarchartState.isLoading) barchartIsLoading$: Observable<boolean>;
constructor(private store: Store) { }
ngOnInit(): void {
this.store.dispatch([
new BarchartActions.Fetch(),
]);
}
}
charts.component.spec.ts
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NgxsModule, Store } from '@ngxs/store';
import { ChartsComponent } from './charts.component';
import { BarchartService } from './states/barchart-state/barchart.service';
import { BarchartState } from './states/barchart-state/barchart.state';
import * as BarchartActions from './states/barchart-state/barchart.actions';
describe('ChartsComponent ', () => {
let component: ChartsComponent ;
let fixture: ComponentFixture<ChartsComponent >;
let store: Store;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ChartsComponent ],
imports: [
NgxsModule.forRoot([BarchartState])
],
providers: [
BarchartService
]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ChartsComponent);
component = fixture.componentInstance;
fixture.detectChanges();
store = TestBed.inject(Store);
});
it('should create', () => {
expect(component).toBeTruthy();
});
// I tried doing this but it doesn't work. It gives an error that simpleChartData is undefined
// Can someone please guide what should I write in the test below?
it('it should dispatch barchart fetch action', () => {
store.dispatch(new BarchartActions.Fetch());
const data = store.selectSnapshot(state => state.barchart.simpleChartData);
expect(data).toBe(true);
});
});
barchart.actions.ts
export class Fetch {
static readonly type = '[Barchart] Fetch';
}
任何线索都会有所帮助!谢谢!
我会这样做:
我写了很多评论,所以你可以通过它来理解。
describe('ChartsComponent ', () => {
// add dispatchSpy variable so we will know when it is called
let dispatchSpy: jasmine.Spy;
let component: ChartsComponent ;
let fixture: ComponentFixture<ChartsComponent >;
let store: Store;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ ChartsComponent ],
imports: [
NgxsModule.forRoot([BarchartState])
],
providers: [
BarchartService
]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(ChartsComponent);
component = fixture.componentInstance;
// get a handle on the store before so we can see when dispatch was called
store = TestBed.inject(Store);
// assign dispatchSpy to when store.dispatch is called
// and put callThrough so when it is actually called, call the actual
// implementation so the store gets notified
dispatchSpy = spyOn(store, 'dispatch').and.callThrough();
// the first fixture.detectChanges() we call is when
// ngOnInit is called. That's why we had to get a handle on the store
// before the first fixture.detectChanges()
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
// I tried doing this but it doesn't work. It gives an error that simpleChartData is undefined
// Can someone please guide what should I write in the test below?
it('it should dispatch barchart fetch action', () => {
// it should be as simple as this
// The first fixture.detectChanges calls ngOnInit for us and we have a
// handle on when store.dispatch is called before ngOnInit
expect(dispatchSpy).toHaveBeenCalledWith([new BarchartActions.Fetch(),]);
});
});