如何模拟在 Angular 中组件声明中调用的方法?
How do I mock a method that is called in my component's declaration in Angular?
我有一个 Angular 11 组件,它将用户的时区设置为 属性。
export class AppComponent implements OnInit {
timezone: string = Intl.DateTimeFormat().resolvedOptions().timeZone;
// ...
}
这个效果不错,我觉得1。现在我正在尝试为使用此 属性 的代码编写单元测试。在我的规范文件中,我有这段代码。
describe('AppComponent', () => {
let fixture: ComponentFixture<AppComponent>;
let component: AppComponent;
let loader: HarnessLoader;
beforeEach(
waitForAsync(() => {
spyOn(Intl.DateTimeFormat(), 'resolvedOptions').and.returnValue({
timeZone: 'America/Sao_Paulo', // this is the mocked value
calendar: 'gregory', // ... and the rest is just the output from Europe/London
day: '2-digit',
locale: 'en-GB',
month: '2-digit',
numberingSystem: 'latn',
year: 'numeric',
});
TestBed.configureTestingModule({
declarations: [AppComponent],
}).compileComponents();
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
loader = TestbedHarnessEnvironment.loader(fixture);
})
);
describe('The User Interface', () => {
beforeEach(async () => {
fixture.detectChanges();
component.ngOnInit();
});
it('should render timezone', () => {
const compiled = fixture.nativeElement;
expect(
compiled.querySelector('.tz').textContent
).toContain('America/Sao_Paulo');
});
});
});
代码可以编译,但测试失败并找到我当地的 "Europe/London"
时区。我怀疑我在错误的时间做模拟。
我想也许我的声明需要保存在稍后执行的某个地方,所以我试图将它移到 constructor
和 ngOnInit()
中,但它们都没有改变任何东西。
当我尝试使用 jasmine.clock().install()
和 mockDate()
时,我的测试超时,一切都崩溃了。
我怎样才能让那个模拟工作,以便我的组件得到一个假的时区?
1) 我可能应该更改计算机的时区以检查它是否真的...
您在错误的对象上设置了间谍。
当 运行 Intl.DateTimeFormat()
您在测试和组件中创建一个新对象时。
您可能应该监视 DateTimeFormat。
spyOn<any>(Intl, "DateTimeFormat").and.returnValue({
resolvedOptions: () => ({timeZone: 'MockTimezone'})
})
我有一个 Angular 11 组件,它将用户的时区设置为 属性。
export class AppComponent implements OnInit {
timezone: string = Intl.DateTimeFormat().resolvedOptions().timeZone;
// ...
}
这个效果不错,我觉得1。现在我正在尝试为使用此 属性 的代码编写单元测试。在我的规范文件中,我有这段代码。
describe('AppComponent', () => {
let fixture: ComponentFixture<AppComponent>;
let component: AppComponent;
let loader: HarnessLoader;
beforeEach(
waitForAsync(() => {
spyOn(Intl.DateTimeFormat(), 'resolvedOptions').and.returnValue({
timeZone: 'America/Sao_Paulo', // this is the mocked value
calendar: 'gregory', // ... and the rest is just the output from Europe/London
day: '2-digit',
locale: 'en-GB',
month: '2-digit',
numberingSystem: 'latn',
year: 'numeric',
});
TestBed.configureTestingModule({
declarations: [AppComponent],
}).compileComponents();
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
loader = TestbedHarnessEnvironment.loader(fixture);
})
);
describe('The User Interface', () => {
beforeEach(async () => {
fixture.detectChanges();
component.ngOnInit();
});
it('should render timezone', () => {
const compiled = fixture.nativeElement;
expect(
compiled.querySelector('.tz').textContent
).toContain('America/Sao_Paulo');
});
});
});
代码可以编译,但测试失败并找到我当地的 "Europe/London"
时区。我怀疑我在错误的时间做模拟。
我想也许我的声明需要保存在稍后执行的某个地方,所以我试图将它移到 constructor
和 ngOnInit()
中,但它们都没有改变任何东西。
当我尝试使用 jasmine.clock().install()
和 mockDate()
时,我的测试超时,一切都崩溃了。
我怎样才能让那个模拟工作,以便我的组件得到一个假的时区?
1) 我可能应该更改计算机的时区以检查它是否真的...
您在错误的对象上设置了间谍。
当 运行 Intl.DateTimeFormat()
您在测试和组件中创建一个新对象时。
您可能应该监视 DateTimeFormat。
spyOn<any>(Intl, "DateTimeFormat").and.returnValue({
resolvedOptions: () => ({timeZone: 'MockTimezone'})
})