首页 > 解决方案 > 用 Jest 测试 Angular 指令

问题描述

我们正在将单元测试从 Jasmine 迁移到 Jest。我正在重构测试,并且在涉及测试指令时必须处理一些意想不到的问题。
实际上,创建指令 HTML 内容似乎一切顺利,但无法使用选择器 sush as 访问元素By.css()。它总是返回 null !

// shadow-top-on-scroll.directive.ts

    @Directive({
      selector: '[appShadowTopOnScroll]'
    })
    export class ShadowTopOnScrollDirective implements OnInit {
      shadow = document.createElement('div');
    
      constructor(private el: ElementRef) {
        this.shadow.id = 'shadow';
        // some css
      }
    
      @HostListener('scroll')
      @throttle(500)
      scroll() {
        if (this.el.nativeElement.scrollTop === 0) {
          this.shadow.classList.remove('shadow-bottom-sm');
        } else {
          this.shadow.classList.add('shadow-bottom-sm');
        }
      }
    
      ngOnInit(): void {
        this.el.nativeElement.parentNode?.insertBefore(this.shadow, this.el.nativeElement);
      }
    }

// shadow-top-on-scroll.directive.spec.ts

     @Component({
          templateUrl: './shadow-top-on-scroll.html',
          changeDetection: ChangeDetectionStrategy.OnPush
        })
        class FakeHostComponent {}
        
        describe('ShadowTopOnScrollDirective', () => {
          let component: FakeHostComponent;
          let fixture: ComponentFixture<FakeHostComponent>;
        
          beforeEach(() => {
            TestBed.configureTestingModule({
              declarations: [FakeHostComponent, ShadowTopOnScrollDirective]
            }).compileComponents();
            fixture = TestBed.createComponent(FakeHostComponent);
            component = fixture.componentInstance;
            fixture.detectChanges();
          });
        
          it('should create component', () => {
            expect(component).toBeTruthy(); // this test is OK
          });
        
          it('should xxx', () => {
            console.log(fixture.debugElement.nativeElement.innerHTML);
            /* prints 
               <div>
                 <div id="shadow" class="pb-2" style="margin-bottom: 0.125rem;"></div>
                 <div appshadowtoponscroll="" id="containerToScroll" style="height: 50px; overflow-y: auto">
                     <div style="height: 100px"></div>
                 </div>
               </div> */
            const shadowElement = fixture.debugElement.query(By.css('#shadow'));
            expect(shadowElement).toBeTruthy(); // test fails because shadowElement is null
         });
        });

// shadow-top-on-scroll.html

<div>
  <div id="containerToScroll" appShadowTopOnScroll style="height: 50px; overflow-y: auto">
    <div style="height: 100px"></div>
  </div>
</div>

我不明白为什么我的 css 选择器By.css()不返回元素,而感觉就像成功生成了 HTML。关于发生了什么的任何想法?
我重构了一些其他组件测试,当我调用By.css('#anyId'). 测试仅针对项目的 3 个指令测试失败

标签: htmlangularjestjsangular-directive

解决方案


推荐阅读