【问题标题】:Angular Integration test: testing a function that is called when event from other component is emitted, how do I mock the event data?Angular 集成测试:测试一个在其他组件发出事件时调用的函数,如何模拟事件数据?
【发布时间】:2019-04-22 09:55:59
【问题描述】:

在我的组件 A 中,我有一个函数可以根据组件 B 发出的数据更新视图。我不想集成组件 B 并制作一个实际的组件,即使这对于这个测试来说太复杂了。

我只想调用函数并将数据传递给函数。问题是,将数据作为“事件”发送到组件 A 中的函数似乎不起作用:

  it('should update the video with the data from the edit component', () => {
    let event;
    event.title = 'New Title';
    event.description = 'New Description';
    event.link = 'New Link';
    event.videoCategory = 'New Category';
    event.categories = '2';
    event.a14Only = 0;

    component.updateVideoCard(event);
    fixture.detectChanges();

    expect(component.videoTitle).toBe('New Title');
    expect(component.videoLink).toBe('New Link');
    expect(component.videoDescription).toBe('New Description');
    expect(component.videoCategory).toBe('New Category');
    expect(component.categoryID).toBe('2');
    expect(component.a14Only).toBe('0');
    expect(component.editDisabled).toBeTruthy();
  });

该事件以“未定义”结束。我还尝试将其设为一个名为“事件”的 javascript 对象,其中包含键值对,但也没有成功。

component.updateEvent(data) 代码:

updateVideoCard(event) {
    this.videoTitle = event.title;
    this.videoDescription = event.description;
    this.videoLink = event.link;
    this.videoCategory = event.category;
    this.categoryID = event.categories;
    if (event.a14Only === 1) {
      this.a14Only = true;
    } else {
      this.a14Only = false;
    }
    this.enableEditor = false;
    this.notification.done(`${this.videoTitle} updated successfully.`);
  }

【问题讨论】:

  • 这看起来像是 DebugElement 类中 triggerEventHandler 的工作:angular.io/api/core/DebugElement#triggerEventHandler 如果您发布组件的代码,我可以给您一个代码示例。
  • 你能和我们分享component.updateVideoCard(event)吗?
  • @fmontes 谢谢。我会马上试一试!当然!我用这段代码编辑了我的帖子。请注意,这是我们使用触发事件和数据的地方。
  • 嗨@SebastianG,我们需要看到的是组件本身的代码,而不是对它们的测试。你能提供那个代码吗?
  • @fmontes 它就在上面的线程中。

标签: angular jasmine angular-test angular-event-emitter


【解决方案1】:

我查看了 DebugElement.triggerEvent,但不幸的是,文档已经过时,而且我自己也没有很幸运地弄清楚如何去做。无论如何,它似乎也需要集成第二个组件。

我最终集成了这两个组件,并使用来自第二个组件的标准 JSON 对象来触发它,如下所示:

describe('VideoCardComponent', () => {
  let component: VideoCardComponent;
  let fixture: ComponentFixture<VideoCardComponent>;
  let fixture2: ComponentFixture<EditVideoComponent>;
  let component2: EditVideoComponent;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        MatCardModule,
        MatButtonModule,
        BrowserAnimationsModule,
        FontAwesomeModule,
        BrowserModule,
        FlexLayoutModule,
        RouterTestingModule,
        ReactiveFormsModule,
        FormsModule,
        MatSelectModule,
        MatOptionModule,
        MatInputModule,
        MatSlideToggleModule
      ],
      declarations: [VideoCardComponent, SafepipePipe, EditVideoComponent],
      providers: [
        { provide: RestService, useClass: RestStub },
        { provide: NotificationService, useClass: NotificationStub }
      ],
      schemas: [NO_ERRORS_SCHEMA]
    })
      .compileComponents()
      .then(() => {
        fixture2 = TestBed.createComponent(EditVideoComponent);
        fixture = TestBed.createComponent(VideoCardComponent);
        component = fixture.componentInstance;
        component2 = fixture2.componentInstance;
        fixture2.detectChanges();
        fixture.detectChanges();
      });
  }));

您可以看到我刚刚将其命名为 component2 和 fixture2 并在同一个测试台中添加了两者的依赖项。

我可能会将它们命名为更相关的名称,而不是 component 和 component2。

固定测试:

it('should update the video with the data from the edit component', () => {
    const data = [
      {
        title: 'New Title',
        description: 'New Description',
        link: 'New Link',
        category: 'New Category',
        categories: '2',
        a14Only: 0
      }
    ];

    component2.updateVideoCard.subscribe(newVideo => {
      component.updateVideoCard(newVideo);
      expect(component.videoTitle).toBe('New Title');
      expect(component.videoLink).toBe('New Link');
      expect(component.videoDescription).toBe('New Description');
      expect(component.videoCategory).toBe('New Category');
      expect(component.categoryID).toBe('2');
      expect(component.a14Only).toBeFalsy();
      expect(component.editDisabled).toBeFalsy();
    });

    component2.updateLocalVideoData(data);

    fixture2.detectChanges();
    fixture.detectChanges();
  });

【讨论】:

    猜你喜欢
    • 2018-03-19
    • 2019-05-02
    • 2020-11-30
    • 2021-02-04
    • 2018-02-15
    • 2017-03-29
    • 1970-01-01
    • 2020-12-17
    • 1970-01-01
    相关资源
    最近更新 更多