我很难理解为什么我无法使用
and.returnValue()
更改模拟服务函数的返回值,如 Jasmine 文档中所述。我简化了我的测试文件来演示我的模拟策略,但其要点是在组件初始化时我需要 StateService.getUserId()
返回示例字符串或空字符串。我最初将其返回值设置为“1234”,但在我的测试中,我需要让它返回一个空字符串来测试其他一些条件。
describe('MyComponent', () => {
let comp: MyComponent;
let fixture: ComponentFixture<MyComponent>;
let mockStateService = jasmine.createSpyObj('StateService', {
getUserId: '1234',
});
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [MyComponent],
providers: [
// .....
[{ provide: StateService, useValue: mockStateService }],
],
});
fixture = TestBed.createComponent(MyComponent);
comp = fixture.componentInstance;
fixture.detectChanges();
});
describe('OnInit', () => {
it('should do some other things when userId doesnt exist', () => {
mockStateService.getUserId.and.returnValue('');
fixture.detectChanges(); // not sure I need this, but removing it doesn't fix the issue either
expect(comp.userId).toBe('');
});
});
});
上述测试总是失败,因为 userId 始终是间谍“1234”的初始返回值,即使在测试中告诉它返回空字符串之后也是如此。
状态.service.ts:
getUserId = () => {
return this.userId;
};
我的组件.ts:
ngOnInit() {
this.userId = this.stateService.getUserId();
if (!this.userId ) {
// ......
} else {
// ......
}
}
正如评论者所说,运行
detectChanges()
应该在设置模拟值之前运行 ngOnInit()
。更改模拟中的值不会导致 ngOnInit() to rerun on the next
detectChanges()`。
也就是说,我确实注意到了一些让我觉得奇怪的事情。
在你的真实代码中
getUserId
是一个方法:
getUserId = () => {
return this.userId;
};
在你的模拟中,
getUserId
是一个属性:
let mockStateService = jasmine.createSpyObj('StateService', {
getUserId: '1234',
});
所以,我会更改模拟以使用方法:
let mockStateService = jasmine.createSpyObj('StateService', {
getUserId = () => {
return '1234';
};
});