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();
  });
});