如何在仓位策略中为订阅编写单元测试?

How to write a unit test for a subscription inside a position strategy?

提问人:Irin 提问时间:11/4/2023 更新时间:11/5/2023 访问量:42

问:

我正在开发一个 Angular 应用程序,我有一个指令,我使用 Angular CDK 覆盖创建仓位策略。这是我的代码的简化版本:

const positionStrategy = this.overlay
  .position()
  .flexibleConnectedTo(this.elementRef)
  .withPositions([
    {
      originX: 'center',
      originY: 'bottom',
      overlayX: 'center',
      overlayY: 'top',
    },
  ])
  .withFlexibleDimensions(false)
  .withTransformOriginOn('.test')
  .withPush(false);

positionStrategy.positionChanges.subscribe((change: ConnectedOverlayPositionChange) => {
  // My code here
});

我想编写一个单元测试,以确保 positionStrategy.positionChanges 中的订阅按预期工作。但是,我在单元测试中涵盖这部分代码时遇到了问题。

有人可以帮我编写一个单元测试来涵盖订阅并允许我测试订阅中代码的行为吗?

我已经尝试创建一个测试用例,但我不确定如何模拟或监视 positionStrategy 并触发位置变化以测试订阅。

有关如何为此方案设置单元测试的任何指导或示例将不胜感激。谢谢!

角度 单元测试 业力茉莉花

评论


答:

0赞 Mohamed Oussema Njimi 11/4/2023 #1

测试 Angular CDK Overlay 的订阅可能有点棘手,但这是可行的。要对此进行测试,您需要创建一个 和 的模型。positionChangesOverlayRefConnectedPositionStrategy

import { Component, Directive, ElementRef } from '@angular/core';
import { Overlay, OverlayRef } from '@angular/cdk/overlay';
import { ConnectedPositionStrategy } from '@angular/cdk/overlay';
import { TestBed, ComponentFixture, async } from '@angular/core/testing';
import { MyDirective } from './my.directive'; // Import your directive

@Directive({
  selector: '[myDirective]',
})
class MyDirectiveMock extends MyDirective {
  constructor(
    elementRef: ElementRef,
    overlay: Overlay,
  ) {
    super(elementRef, overlay);
  }
}

@Component({
  template: `
    <div myDirective></div>
  `,
})
class TestComponent {}

describe('MyDirective', () => {
  let fixture: ComponentFixture<TestComponent>;
  let overlay: Overlay;
  let overlayRef: OverlayRef;
  let connectedPositionStrategy: jasmine.SpyObj<ConnectedPositionStrategy>;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [MyDirectiveMock, TestComponent],
      providers: [
        Overlay,
      ],
    }).compileComponents();

    fixture = TestBed.createComponent(TestComponent);
    overlay = TestBed.inject(Overlay);

    // Create a spy object for ConnectedPositionStrategy
    connectedPositionStrategy = jasmine.createSpyObj<ConnectedPositionStrategy>('ConnectedPositionStrategy', ['withPositions', 'withFlexibleDimensions', 'withTransformOriginOn', 'withPush']);
    overlayRef = jasmine.createSpyObj<OverlayRef>('OverlayRef', ['dispose']);
    overlayRef.getConfig.and.returnValue({ positionStrategy: connectedPositionStrategy });
  }));

  it('should handle position strategy changes', () => {
    // Create an instance of your directive
    const directiveInstance = fixture.debugElement.query(By.directive(MyDirectiveMock)).injector.get(MyDirectiveMock);

    // Manually trigger a position change
    connectedPositionStrategy.positionChanges.next({} as ConnectedOverlayPositionChange);

    // Assert that your code inside the subscription has been called or test its behavior
    // For example, you can check if a method was called in your directive
    expect(directiveInstance.someMethod).toHaveBeenCalled();
  });
});

评论

0赞 Irin 11/6/2023
感谢您的解决方案。它帮助我了解如何嘲笑它。