如何在 angular 7 中对 getCurrentNavigation().extras.state 进行单元测试
How to do unit testing for getCurrentNavigation().extras.state in angular 7
我正在尝试使用 jasmine 为 getCurrentNavigation() 编写单元测试。extras.state。
为了解决这个问题,我试过监视这个路由器方法。
我的组件文件,
@Component({
selector: 'app-location-list',
templateUrl: './location-list.component.html',
styleUrls: ['./location-list.component.scss']
})
export class LocationListComponent implements OnInit{
locationId;
locationName;
constructor(private activatedRoute: ActivatedRoute, private router: Router) {
if (this.router.getCurrentNavigation().extras.state) {
this.locationId = this.router.getCurrentNavigation().extras.state.locationId;
}
if (this.router.getCurrentNavigation().extras.state) {
this.locationName = this.router.getCurrentNavigation().extras.state.locationName;
}
}
ngOnInit() { }
}
我的规范文件,
describe('LocationListComponent ', () => {
let component: LocationListComponent ;
let fixture: ComponentFixture<LocationListComponent >;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
LocationListComponent
],
providers: []
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LocationListComponent );
component = fixture.componentInstance;
spyOn(Router.prototype, 'getCurrentNavigation').and.returnValues({ 'extras': { 'state': { 'locationId': 100, 'locationName': "UK" } } });
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
但是我收到以下错误,
TypeError: Cannot read property 'extras' of null
谁能帮我解决这个问题。我正在使用 Angular 7.2
您需要从 fixture 获取路由器实例
router = fixture.debugElement.injector.get(Router);
您可以使用 stub
和 useClass
轻松做到这一点,如果您可以在单独的文件和 export class RouterStub
中创建它,也可以在其他 spec
文件中重复使用, 试试:
在 spec
文件中创建一个 stub
,其方法与 Router
:
相同
class RouterStub{
getCurrentNavigation(){
return {
extras: {
state:{
locationId: 'someId',
locationName: 'someName'
}
}
}
}
}
并在 beforeEach()
块中:
describe('LocationListComponent ', () => {
let component: LocationListComponent ;
let fixture: ComponentFixture<LocationListComponent >;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
LocationListComponent
],
providers: [ {provide: Router, useClass: RouterStub}]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LocationListComponent );
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
如果我们尝试同时使用 RouterTestingModule
和 {provide: Router, useClass: RouterStub}
它将抛出 cannot read property 'root' of undefined
的错误
所以我们可以直接为 Route 和它的 return 值创建 spy
describe('LocationListComponent', () => {
let component: LocationListComponent ;
let fixture: ComponentFixture<LocationListComponent>;
let router: jasmine.SpyObj<Router>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
LocationListComponent
],
})
.compileComponents();
}));
beforeEach(() => {
router = TestBed.get(Router);
spyOn(router, 'getCurrentNavigation').and.returnValue({ extras: { state: { message: 'msg'} } } as any);
fixture = TestBed.createComponent(LocationListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
router.getCurrentNavigation()
的单元测试可以通过 3 个简单的步骤完成:
创建模拟路由器对象:
const mockRouter = {
getCurrentNavigation: jasmine.createSpy('getCurrentNavigation')
};
将其注入 providers
数组:
providers: [{ provide: Router, useValue: mockRouter }]
Return beforeEach()
函数中所需的模拟值
mockRouter.getCurrentNavigation.and.returnValue({
extras: {
state: {
test: ''
}
}
});
我正在尝试使用 jasmine 为 getCurrentNavigation() 编写单元测试。extras.state。
为了解决这个问题,我试过监视这个路由器方法。
我的组件文件,
@Component({
selector: 'app-location-list',
templateUrl: './location-list.component.html',
styleUrls: ['./location-list.component.scss']
})
export class LocationListComponent implements OnInit{
locationId;
locationName;
constructor(private activatedRoute: ActivatedRoute, private router: Router) {
if (this.router.getCurrentNavigation().extras.state) {
this.locationId = this.router.getCurrentNavigation().extras.state.locationId;
}
if (this.router.getCurrentNavigation().extras.state) {
this.locationName = this.router.getCurrentNavigation().extras.state.locationName;
}
}
ngOnInit() { }
}
我的规范文件,
describe('LocationListComponent ', () => {
let component: LocationListComponent ;
let fixture: ComponentFixture<LocationListComponent >;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
LocationListComponent
],
providers: []
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LocationListComponent );
component = fixture.componentInstance;
spyOn(Router.prototype, 'getCurrentNavigation').and.returnValues({ 'extras': { 'state': { 'locationId': 100, 'locationName': "UK" } } });
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
但是我收到以下错误,
TypeError: Cannot read property 'extras' of null
谁能帮我解决这个问题。我正在使用 Angular 7.2
您需要从 fixture 获取路由器实例
router = fixture.debugElement.injector.get(Router);
您可以使用 stub
和 useClass
轻松做到这一点,如果您可以在单独的文件和 export class RouterStub
中创建它,也可以在其他 spec
文件中重复使用, 试试:
在 spec
文件中创建一个 stub
,其方法与 Router
:
class RouterStub{
getCurrentNavigation(){
return {
extras: {
state:{
locationId: 'someId',
locationName: 'someName'
}
}
}
}
}
并在 beforeEach()
块中:
describe('LocationListComponent ', () => {
let component: LocationListComponent ;
let fixture: ComponentFixture<LocationListComponent >;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
LocationListComponent
],
providers: [ {provide: Router, useClass: RouterStub}]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(LocationListComponent );
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
如果我们尝试同时使用 RouterTestingModule
和 {provide: Router, useClass: RouterStub}
它将抛出 cannot read property 'root' of undefined
所以我们可以直接为 Route 和它的 return 值创建 spy
describe('LocationListComponent', () => {
let component: LocationListComponent ;
let fixture: ComponentFixture<LocationListComponent>;
let router: jasmine.SpyObj<Router>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
LocationListComponent
],
})
.compileComponents();
}));
beforeEach(() => {
router = TestBed.get(Router);
spyOn(router, 'getCurrentNavigation').and.returnValue({ extras: { state: { message: 'msg'} } } as any);
fixture = TestBed.createComponent(LocationListComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});
router.getCurrentNavigation()
的单元测试可以通过 3 个简单的步骤完成:
创建模拟路由器对象:
const mockRouter = { getCurrentNavigation: jasmine.createSpy('getCurrentNavigation') };
将其注入
providers
数组:providers: [{ provide: Router, useValue: mockRouter }]
Return
beforeEach()
函数中所需的模拟值mockRouter.getCurrentNavigation.and.returnValue({ extras: { state: { test: '' } } });