如何调用模拟方法而不被间谍检测到?
How can a mocked method be called and not be detected by spy?
这是我的组件:
@Component({
selector: 'app-signup',
templateUrl: './signup.component.html',
styleUrls: ['./signup.component.scss']
})
export class SignUpComponent implements OnInit {
specialLink: string;
constructor(
private activatedRoute: ActivatedRoute,
) {
this.specialLink = this.activatedRoute.snapshot.params.id;
console.log('TEST1', this.specialLink);
if (this.specialLink !== undefined) {
this.setSpecialSignup();
}
}
setSpecialSignup() {
console.log("CALLED;");
}
这是我的测试:
describe('SignUpComponent', () => {
let component: SignUpComponent;
let fixture: ComponentFixture<SignUpComponent>;
let ActivatedRouteMock: any;
beforeEach(async(() => {
ActivatedRouteMock = {
snapshot: {
params: { id: 123 }
},
};
TestBed.configureTestingModule({
declarations: [ SignUpComponent ],
imports: [ RouterTestingModule ],
providers: [
{provide: ActivatedRoute, useValue: ActivatedRouteMock}
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(SignUpComponent);
component = fixture.componentInstance;
});
describe('Patient Side', () => {
it('should call setSpecialSignup() when user is coming from specialLink', () => {
spyOn(component, 'setSpecialSignup');
fixture.detectChanges();
expect(component.setSpecialSignup).toHaveBeenCalled();
});
我正在测试是否调用了 setSpecialSignup。它是! 2'console.log'证明了。那么,为什么会出现此错误:Expected spy setSpecialSignup to have been called.
?
我错过了什么?
看来我需要能够更改 ActivatedRouteMock.snapshot.params.id 的值。有时它必须是未定义的,有时它必须是 'something'。我怎样才能做到这一点 ?我试过 ActivatedRouteMock.snapshot.params.id = 'something'
但它根本没有改变值,即使使用 fixture.detectChanges() 也是如此。我该怎么做?
你能把你放在构造函数中的代码移动到 ngOnInit()
@Component({
selector: 'app-signup',
templateUrl: './signup.component.html',
styleUrls: ['./signup.component.scss']
})
export class SignUpComponent implements OnInit {
specialLink: string;
constructor(
private activatedRoute: ActivatedRoute,
) {
}
ngOnInit(){
this.specialLink = this.activatedRoute.snapshot.params.id;
console.log('TEST1', this.specialLink);
if (this.specialLink !== undefined) {
this.setSpecialSignup();
}
}
setSpecialSignup() {
console.log("CALLED;");
}
你能试试下面的代码吗?
describe('SignUpComponent', () => {
let component: SignUpComponent;
let fixture: ComponentFixture<SignUpComponent>;
let ActivatedRouteMock: any;
beforeEach(async(() => {
ActivatedRouteMock = {
snapshot: {
params: { id: 123 }
},
};
TestBed.configureTestingModule({
declarations: [ SignUpComponent ],
imports: [ RouterTestingModule ],
providers: [
{provide: ActivatedRoute, useValue: ActivatedRouteMock}
]
})
.compileComponents().then(() => {
fixture = TestBed.createComponent(PriceModelListComponent);
component = fixture.componentInstance;
});
}));
describe('Patient Side', () => {
it('should call setSpecialSignup() when user is coming from specialLink', () => {
spyOn(component, 'setSpecialSignup');
fixture.detectChanges();
expect(component.setSpecialSignup).toHaveBeenCalled();
});
模拟参数
规范中的提供者内部
providers: [ { provide: ActivatedRoute, useValue: { // Mock queryParams: of( { id_params: 'id_params_test' } ), params: of( { id_query_params: 'id_query_params_test' } ) } } ],
正如我们所见,setSpecialSignup
在 constructor
内部被调用。 constructor
在此行 fixture = TestBed.createComponent(SignUpComponent);
上被调用。而你创造一个间谍为时已晚。如果您希望此功能更容易测试,请将组件的逻辑移动到 ngOnInit
生命周期挂钩。它将在第一个 fixture.detectChanges()
上被调用,你的测试应该没问题
constructor(
private activatedRoute: ActivatedRoute,
) { }
ngOnInit() {
this.specialLink = this.activatedRoute.snapshot.params.id;
console.log('TEST1', this.specialLink);
if (this.specialLink !== undefined) {
this.setSpecialSignup();
}
}
这是我的组件:
@Component({
selector: 'app-signup',
templateUrl: './signup.component.html',
styleUrls: ['./signup.component.scss']
})
export class SignUpComponent implements OnInit {
specialLink: string;
constructor(
private activatedRoute: ActivatedRoute,
) {
this.specialLink = this.activatedRoute.snapshot.params.id;
console.log('TEST1', this.specialLink);
if (this.specialLink !== undefined) {
this.setSpecialSignup();
}
}
setSpecialSignup() {
console.log("CALLED;");
}
这是我的测试:
describe('SignUpComponent', () => {
let component: SignUpComponent;
let fixture: ComponentFixture<SignUpComponent>;
let ActivatedRouteMock: any;
beforeEach(async(() => {
ActivatedRouteMock = {
snapshot: {
params: { id: 123 }
},
};
TestBed.configureTestingModule({
declarations: [ SignUpComponent ],
imports: [ RouterTestingModule ],
providers: [
{provide: ActivatedRoute, useValue: ActivatedRouteMock}
]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(SignUpComponent);
component = fixture.componentInstance;
});
describe('Patient Side', () => {
it('should call setSpecialSignup() when user is coming from specialLink', () => {
spyOn(component, 'setSpecialSignup');
fixture.detectChanges();
expect(component.setSpecialSignup).toHaveBeenCalled();
});
我正在测试是否调用了 setSpecialSignup。它是! 2'console.log'证明了。那么,为什么会出现此错误:Expected spy setSpecialSignup to have been called.
?
我错过了什么?
看来我需要能够更改 ActivatedRouteMock.snapshot.params.id 的值。有时它必须是未定义的,有时它必须是 'something'。我怎样才能做到这一点 ?我试过 ActivatedRouteMock.snapshot.params.id = 'something'
但它根本没有改变值,即使使用 fixture.detectChanges() 也是如此。我该怎么做?
你能把你放在构造函数中的代码移动到 ngOnInit()
@Component({
selector: 'app-signup',
templateUrl: './signup.component.html',
styleUrls: ['./signup.component.scss']
})
export class SignUpComponent implements OnInit {
specialLink: string;
constructor(
private activatedRoute: ActivatedRoute,
) {
}
ngOnInit(){
this.specialLink = this.activatedRoute.snapshot.params.id;
console.log('TEST1', this.specialLink);
if (this.specialLink !== undefined) {
this.setSpecialSignup();
}
}
setSpecialSignup() {
console.log("CALLED;");
}
你能试试下面的代码吗?
describe('SignUpComponent', () => {
let component: SignUpComponent;
let fixture: ComponentFixture<SignUpComponent>;
let ActivatedRouteMock: any;
beforeEach(async(() => {
ActivatedRouteMock = {
snapshot: {
params: { id: 123 }
},
};
TestBed.configureTestingModule({
declarations: [ SignUpComponent ],
imports: [ RouterTestingModule ],
providers: [
{provide: ActivatedRoute, useValue: ActivatedRouteMock}
]
})
.compileComponents().then(() => {
fixture = TestBed.createComponent(PriceModelListComponent);
component = fixture.componentInstance;
});
}));
describe('Patient Side', () => {
it('should call setSpecialSignup() when user is coming from specialLink', () => {
spyOn(component, 'setSpecialSignup');
fixture.detectChanges();
expect(component.setSpecialSignup).toHaveBeenCalled();
});
模拟参数
规范中的提供者内部
providers: [ { provide: ActivatedRoute, useValue: { // Mock queryParams: of( { id_params: 'id_params_test' } ), params: of( { id_query_params: 'id_query_params_test' } ) } } ],
正如我们所见,setSpecialSignup
在 constructor
内部被调用。 constructor
在此行 fixture = TestBed.createComponent(SignUpComponent);
上被调用。而你创造一个间谍为时已晚。如果您希望此功能更容易测试,请将组件的逻辑移动到 ngOnInit
生命周期挂钩。它将在第一个 fixture.detectChanges()
上被调用,你的测试应该没问题
constructor(
private activatedRoute: ActivatedRoute,
) { }
ngOnInit() {
this.specialLink = this.activatedRoute.snapshot.params.id;
console.log('TEST1', this.specialLink);
if (this.specialLink !== undefined) {
this.setSpecialSignup();
}
}