Angular Jasmine error : TypeError: Cannot read property 'value' of undefined
Angular Jasmine error : TypeError: Cannot read property 'value' of undefined
我已经使用 Jasmine 编写了一个 angular 测试,并且由于未正确模拟而在事件代码段上出现错误。你能告诉我哪里错了吗
我得到的错误是
TypeError: 无法读取未定义的 属性 'value'
在这个方法中
it('should trigger change method on select value change',fakeAsync(() => {}
我试过像这样模拟事件对象测试class
const event = { event: { target: { value: 42 }}};
测试
import { Mock } from 'ts-mocks';
fdescribe('TestTypeComponent', () => {
let component: TestTypeComponent;
let fixture: ComponentFixture<TestTypeComponent>;
let mockTestTypeService;
let mockCommonStore;
const testTypeModel = TestTypeModelObjectMock;
const event = { event: { target: { value: 42 }}};
const setupComponent = () => {
fixture = TestBed.createComponent(TestTypeComponent);
component = fixture.componentInstance;
fixture.detectChanges();
};
beforeEach (() => {
mockCommonStore = new Mock<CommonStore>({
setSelectedTestType: () => void(1),
getSelectedTestType: () => of(1)
});
mockTestTypeService = new Mock<TestTypeService>({
getTestTypes: () => of(testTypeModel)
});
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
declarations: [TestTypeComponent],
providers: [
{ provide: TestTypeService, useFactory: () => mockTestTypeService.Object },
{ provide: CommonStore, useFactory: () => mockCommonStore.Object }
],
}).compileComponents();
});
it('should create', () => {
setupComponent();
expect(component).toBeDefined();
});
it('should trigger change method on select value change',fakeAsync(() => {
setupComponent();
var select = fixture.debugElement.query(By.css('#selectTestType'))
.triggerEventHandler("change", {});
component.onSelectingTestType(event);
flush();
fixture.whenStable().then(res => {
expect(component.commonStore.setSelectedTestType).toHaveBeenCalled();
});
}));
});
组件
onSelectingTestType(event: any) {
let typeId = 0;
if (event.target.value !== 'All') {
typeId = +event.target.value;
}
this.commonStore.setSelectedTestType(typeId);
CommonStore
private selectedAccountType = new Subject<number>();
setSelectedAccountType(selectedTypeId: number) {
this.selectedAccountType.next(selectedTypeId);
}
你应该像这样模拟你的对象:
const event = { target: { value: 42 }};
否则你必须做,event.event
。
另一个问题是您的 triggerEventHandler
。第二个参数应该是您在上面创建的事件对象:
.triggerEventHandler("change", event);
这样你就不必调用 component.onSelectingTestType(event);
,因为组件已经从模板调用了它(我猜)。
另外你不应该使用 fakeAsync
。只有当你真的在伪造计时器时。您可以使用本机 js await/async
模式。
还有一点就是你应该在provider中使用useValue
。这将对此进行完整的测试:
fdescribe('TestTypeComponent', () => {
let component: TestTypeComponent;
let fixture: ComponentFixture<TestTypeComponent>;
let mockTestTypeService;
let mockCommonStore;
const testTypeModel = TestTypeModelObjectMock;
const event = { target: { value: 42 } };
const setupComponent = () => {
fixture = TestBed.createComponent(TestTypeComponent);
component = fixture.componentInstance;
fixture.detectChanges();
};
beforeEach (() => {
mockCommonStore = new Mock<CommonStore>({
setSelectedTestType: () => void(1),
getSelectedTestType: () => of(1)
});
mockTestTypeService = new Mock<TestTypeService>({
getTestTypes: () => of(testTypeModel)
});
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
declarations: [TestTypeComponent],
providers: [
{ provide: TestTypeService, useValue: mockTestTypeService },
{ provide: CommonStore, useValue: mockCommonStore }
],
}).compileComponents();
});
it('should create', () => {
setupComponent();
expect(component).toBeDefined();
});
it('should trigger change method on select value change', async () => {
setupComponent();
fixture.debugElement.query(By.css('#selectTestType'))
.triggerEventHandler("change", event);
await fixture.whenStable();
expect(component.commonStore.setSelectedTestType).toHaveBeenCalled();
});
});
我已经使用 Jasmine 编写了一个 angular 测试,并且由于未正确模拟而在事件代码段上出现错误。你能告诉我哪里错了吗
我得到的错误是
TypeError: 无法读取未定义的 属性 'value'
在这个方法中
it('should trigger change method on select value change',fakeAsync(() => {}
我试过像这样模拟事件对象测试class
const event = { event: { target: { value: 42 }}};
测试
import { Mock } from 'ts-mocks';
fdescribe('TestTypeComponent', () => {
let component: TestTypeComponent;
let fixture: ComponentFixture<TestTypeComponent>;
let mockTestTypeService;
let mockCommonStore;
const testTypeModel = TestTypeModelObjectMock;
const event = { event: { target: { value: 42 }}};
const setupComponent = () => {
fixture = TestBed.createComponent(TestTypeComponent);
component = fixture.componentInstance;
fixture.detectChanges();
};
beforeEach (() => {
mockCommonStore = new Mock<CommonStore>({
setSelectedTestType: () => void(1),
getSelectedTestType: () => of(1)
});
mockTestTypeService = new Mock<TestTypeService>({
getTestTypes: () => of(testTypeModel)
});
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
declarations: [TestTypeComponent],
providers: [
{ provide: TestTypeService, useFactory: () => mockTestTypeService.Object },
{ provide: CommonStore, useFactory: () => mockCommonStore.Object }
],
}).compileComponents();
});
it('should create', () => {
setupComponent();
expect(component).toBeDefined();
});
it('should trigger change method on select value change',fakeAsync(() => {
setupComponent();
var select = fixture.debugElement.query(By.css('#selectTestType'))
.triggerEventHandler("change", {});
component.onSelectingTestType(event);
flush();
fixture.whenStable().then(res => {
expect(component.commonStore.setSelectedTestType).toHaveBeenCalled();
});
}));
});
组件
onSelectingTestType(event: any) {
let typeId = 0;
if (event.target.value !== 'All') {
typeId = +event.target.value;
}
this.commonStore.setSelectedTestType(typeId);
CommonStore
private selectedAccountType = new Subject<number>();
setSelectedAccountType(selectedTypeId: number) {
this.selectedAccountType.next(selectedTypeId);
}
你应该像这样模拟你的对象:
const event = { target: { value: 42 }};
否则你必须做,event.event
。
另一个问题是您的 triggerEventHandler
。第二个参数应该是您在上面创建的事件对象:
.triggerEventHandler("change", event);
这样你就不必调用 component.onSelectingTestType(event);
,因为组件已经从模板调用了它(我猜)。
另外你不应该使用 fakeAsync
。只有当你真的在伪造计时器时。您可以使用本机 js await/async
模式。
还有一点就是你应该在provider中使用useValue
。这将对此进行完整的测试:
fdescribe('TestTypeComponent', () => {
let component: TestTypeComponent;
let fixture: ComponentFixture<TestTypeComponent>;
let mockTestTypeService;
let mockCommonStore;
const testTypeModel = TestTypeModelObjectMock;
const event = { target: { value: 42 } };
const setupComponent = () => {
fixture = TestBed.createComponent(TestTypeComponent);
component = fixture.componentInstance;
fixture.detectChanges();
};
beforeEach (() => {
mockCommonStore = new Mock<CommonStore>({
setSelectedTestType: () => void(1),
getSelectedTestType: () => of(1)
});
mockTestTypeService = new Mock<TestTypeService>({
getTestTypes: () => of(testTypeModel)
});
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
declarations: [TestTypeComponent],
providers: [
{ provide: TestTypeService, useValue: mockTestTypeService },
{ provide: CommonStore, useValue: mockCommonStore }
],
}).compileComponents();
});
it('should create', () => {
setupComponent();
expect(component).toBeDefined();
});
it('should trigger change method on select value change', async () => {
setupComponent();
fixture.debugElement.query(By.css('#selectTestType'))
.triggerEventHandler("change", event);
await fixture.whenStable();
expect(component.commonStore.setSelectedTestType).toHaveBeenCalled();
});
});