在 describe 中定义的变量在 angular 测试 (jest/jasmine) 的外部函数中是 "undefined"
Variables defined in describe is "undefined" in outer functions in angular test (jest/jasmine)
我有这样的代码:
// imports
describe('AdminGetRightsComponent', () => {
// Declare variables to be re-initialized before each test suite
let fixture: ComponentFixture<AdminGetRightsComponent>;
let component: AdminGetRightsComponent;
let router: Router;
let location: Location;
let debugElement: DebugElement;
window.alert = jest.fn();
// Create service stubs
let nxDialogServiceStub: Partial<NxDialogService>;
nxDialogServiceStub = {};
let ServicesRmAdminServiceStub: Partial<ServicesRmAdminService>;
ServicesRmAdminServiceStub = {
// Simulate API call, wait for 1000 milliseconds
async getRights(contactIds: string[]) {
await new Promise(resolve => setTimeout(resolve, 0));
return {
body: TEST_API_RESPONES_BODY
}
}
};
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ AdminGetRightsComponent ],
imports: [
RouterTestingModule.withRoutes([{ path: '', component: AdminGetRightsComponent }]),
HttpClientTestingModule,
BrowserAnimationsModule,
modulesForTests
],
providers: [
{ provide: NxDialogService },
{ provide: ServicesRmAdminService, useValue : ServicesRmAdminServiceStub},
{ provide: ServicesFileManagementService }
]
})
.compileComponents();
});
beforeEach(() => {
router = TestBed.inject(Router);
location = TestBed.inject(Location);
fixture = TestBed.createComponent(AdminGetRightsComponent);
component = fixture.componentInstance;
component.downloadCSV = jest.fn(() => {
component.fileUploaderComponent.removeFile(component.files[0]);
});
debugElement = fixture.debugElement;
fixture.ngZone.run(() => {
router.initialNavigation();
});
fixture.detectChanges();
});
describe('When uploaded a file', () => {
beforeEach((done) => {
fixture.detectChanges();
uploadFileToComponent(component);
setTimeout(done, TEST_DEFAULT_TIMEOUT);
});
afterEach((done) => {
fixture.detectChanges();
// Remove the file
component.files.length > 0 && component.fileUploaderComponent.fileDeleted.emit(component.files[0]);
setTimeout(done, TEST_DEFAULT_TIMEOUT);
});
it('should have the right UI elements', () => {
fixture.detectChanges();
expect(...).toBe(...);
});
describe('When clicked on the delete file button', () => {
beforeEach((done) => {
fixture.detectChanges();
getNativeElement('nx-file-upload-delete button', debugElement).click();
setTimeout(done, TEST_DEFAULT_TIMEOUT);
});
it('should remove the right UI elements', () => {
fixture.detectChanges();
expect(...).toBe(...);
});
});
// other code
});
});
在我的代码中,我有很多这样的 beforeEach
(至少 8 或 9 个地方):
beforeEach((done) => {
fixture.detectChanges();
getNativeElement('nx-file-upload-delete button', debugElement).click();
setTimeout(done, TEST_DEFAULT_TIMEOUT);
});
fixture.detectChanges()
和 setTimeout(...)
是重复的代码,我不想要它。
一开始我是这样写的:
function _beforeEach(callback) {
eval('fixture.detectChanges()');
beforeEach((done) => {
callback();
setTimeout(done, TEST_DEFAULT_TIMEOUT);
})
}
然后我用这个_beforeEach
替换了之前的所有beforeEach
,这可以帮助我减少每次调用的2行代码。但它说 ReferenceError: fixture is not defined
.
然后我尝试了这样的事情:
function _beforeEach(
callback,
fixture: ComponentFixture<AdminGetRightsComponent>
) {
fixture.detectChanges();
beforeEach((done) => {
callback();
setTimeout(done, TEST_DEFAULT_TIMEOUT);
});
}
并且我用上面的 _beforeEach
替换了之前的所有 beforeEach
,当我用 ng test
启动测试时,我得到了错误 TypeError: Cannot read property 'detectChanges' of undefined
.
有人知道为什么会这样吗?
我想你尝试归档这个:
function _beforeEach(
callback
) {
fixture.detectChanges();
beforeEach((done) => {
callback();
setTimeout(done, TEST_DEFAULT_TIMEOUT);
});
}
虽然我看不到 fixture.detectChanges();
这行的必要性。似乎只是从根 beforeEach
.
复制相同的代码
我也会避免 setTimeout(done, TEST_DEFAULT_TIMEOUT);
会减慢测试 运行 执行时间。在大多数情况下 await fixture.whenStable()
解决等待异步操作完成的问题。如果还不够,那么 fakeAsyncc
和 tick
或 jasmine.clock
可能是一个解决方案。虽然它并不总是有效,但我也偶尔会放弃并使用超时解决方案。
我有这样的代码:
// imports
describe('AdminGetRightsComponent', () => {
// Declare variables to be re-initialized before each test suite
let fixture: ComponentFixture<AdminGetRightsComponent>;
let component: AdminGetRightsComponent;
let router: Router;
let location: Location;
let debugElement: DebugElement;
window.alert = jest.fn();
// Create service stubs
let nxDialogServiceStub: Partial<NxDialogService>;
nxDialogServiceStub = {};
let ServicesRmAdminServiceStub: Partial<ServicesRmAdminService>;
ServicesRmAdminServiceStub = {
// Simulate API call, wait for 1000 milliseconds
async getRights(contactIds: string[]) {
await new Promise(resolve => setTimeout(resolve, 0));
return {
body: TEST_API_RESPONES_BODY
}
}
};
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ AdminGetRightsComponent ],
imports: [
RouterTestingModule.withRoutes([{ path: '', component: AdminGetRightsComponent }]),
HttpClientTestingModule,
BrowserAnimationsModule,
modulesForTests
],
providers: [
{ provide: NxDialogService },
{ provide: ServicesRmAdminService, useValue : ServicesRmAdminServiceStub},
{ provide: ServicesFileManagementService }
]
})
.compileComponents();
});
beforeEach(() => {
router = TestBed.inject(Router);
location = TestBed.inject(Location);
fixture = TestBed.createComponent(AdminGetRightsComponent);
component = fixture.componentInstance;
component.downloadCSV = jest.fn(() => {
component.fileUploaderComponent.removeFile(component.files[0]);
});
debugElement = fixture.debugElement;
fixture.ngZone.run(() => {
router.initialNavigation();
});
fixture.detectChanges();
});
describe('When uploaded a file', () => {
beforeEach((done) => {
fixture.detectChanges();
uploadFileToComponent(component);
setTimeout(done, TEST_DEFAULT_TIMEOUT);
});
afterEach((done) => {
fixture.detectChanges();
// Remove the file
component.files.length > 0 && component.fileUploaderComponent.fileDeleted.emit(component.files[0]);
setTimeout(done, TEST_DEFAULT_TIMEOUT);
});
it('should have the right UI elements', () => {
fixture.detectChanges();
expect(...).toBe(...);
});
describe('When clicked on the delete file button', () => {
beforeEach((done) => {
fixture.detectChanges();
getNativeElement('nx-file-upload-delete button', debugElement).click();
setTimeout(done, TEST_DEFAULT_TIMEOUT);
});
it('should remove the right UI elements', () => {
fixture.detectChanges();
expect(...).toBe(...);
});
});
// other code
});
});
在我的代码中,我有很多这样的 beforeEach
(至少 8 或 9 个地方):
beforeEach((done) => {
fixture.detectChanges();
getNativeElement('nx-file-upload-delete button', debugElement).click();
setTimeout(done, TEST_DEFAULT_TIMEOUT);
});
fixture.detectChanges()
和 setTimeout(...)
是重复的代码,我不想要它。
一开始我是这样写的:
function _beforeEach(callback) {
eval('fixture.detectChanges()');
beforeEach((done) => {
callback();
setTimeout(done, TEST_DEFAULT_TIMEOUT);
})
}
然后我用这个_beforeEach
替换了之前的所有beforeEach
,这可以帮助我减少每次调用的2行代码。但它说 ReferenceError: fixture is not defined
.
然后我尝试了这样的事情:
function _beforeEach(
callback,
fixture: ComponentFixture<AdminGetRightsComponent>
) {
fixture.detectChanges();
beforeEach((done) => {
callback();
setTimeout(done, TEST_DEFAULT_TIMEOUT);
});
}
并且我用上面的 _beforeEach
替换了之前的所有 beforeEach
,当我用 ng test
启动测试时,我得到了错误 TypeError: Cannot read property 'detectChanges' of undefined
.
有人知道为什么会这样吗?
我想你尝试归档这个:
function _beforeEach(
callback
) {
fixture.detectChanges();
beforeEach((done) => {
callback();
setTimeout(done, TEST_DEFAULT_TIMEOUT);
});
}
虽然我看不到 fixture.detectChanges();
这行的必要性。似乎只是从根 beforeEach
.
我也会避免 setTimeout(done, TEST_DEFAULT_TIMEOUT);
会减慢测试 运行 执行时间。在大多数情况下 await fixture.whenStable()
解决等待异步操作完成的问题。如果还不够,那么 fakeAsyncc
和 tick
或 jasmine.clock
可能是一个解决方案。虽然它并不总是有效,但我也偶尔会放弃并使用超时解决方案。