使用 Jasmine 测试深度嵌套属性的值

发布于 2025-01-09 07:50:22 字数 3326 浏览 0 评论 0原文

我正在尝试使用以下代码测试某些值是否设置为 0 并进行测试:

代码:

this.customShell.customShellApp.element.nativeElement.scrollTop = 0;

测试:

spyOnProperty(component.customShellApp, 'element', 'set').and.returnValue({
  nativeElement: { scrollTop: 0 }
});
expect(component.customShellApp.element.nativeElement.scrollTop).toBe(0);

但我收到以下错误:

Error: <spyOnProperty> : spyOn could not find an object to spy upon for element

Anybody知道如何测试完整的属性吗?该属性来自我们扩展的 CustomShellBase

完整代码如下:

AppComponent.ts

import { Component, Injector, OnDestroy } from '@angular/core';
import { Event, NavigationEnd, Router } from '@angular/router';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { CustomShellBase, CustomShellService } from 'custom-shell-angular';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent extends CustomShellBase implements OnDestroy {
  loading = false;

  protected destroyed$: Subject<boolean> = new Subject();

  constructor(
    protected injector: Injector,
    private router: Router,
    protected shellService: CustomShellService
  ) {
    super(injector);

    this.router.events
      .pipe(takeUntil(this.destroyed$))
      .subscribe((event: Event) => {
        if (event instanceof NavigationEnd) {
          this.customShell.customShellApp.element.nativeElement.scrollTop = 0;
          this.loading = false;
        }
      });
  }

  ngOnDestroy(): void {
    this.destroyed$.next(true);
    this.destroyed$.complete();
  }
}

AppComponent.spec.ts

describe('AppComponent', () => {
  let component: AppComponent;
  let fixture: ComponentFixture<AppComponent>;

  let shellNavService: CustomShellNavService;
  let router: Router;

  const eventSubject = new ReplaySubject<RouterEvent>(1);
  const routerMock = {
    navigate: jasmine.createSpy('navigate'),
    events: eventSubject.asObservable(),
    url: 'test/url'
  };
  
  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [AppComponent],
      providers: [
        CustomShellService,
        { provide: CustomShellNavService, useClass: MockCustomShellNavService },
        { provide: Router, useValue: routerMock },
      ],
      imports: [
        RouterTestingModule.withRoutes(routes)
      ],
      schemas: [CUSTOM_ELEMENTS_SCHEMA]
    });

    fixture = TestBed.createComponent(AppComponent);
    component = fixture.componentInstance;

    shellNavService = TestBed.inject(CustomShellNavService);
    router = TestBed.inject(Router);
  });

  it('should set the loading on FALSE and scroll to the top when a NavigationEnd event happens', () => {
    eventSubject.next(new NavigationEnd(1, '', ''));
    spyOnProperty(component.customShellApp, 'element', 'set').and.returnValue({
      nativeElement: { scrollTop: 0 }
    });
    expect(component.customShellApp.element.nativeElement.scrollTop).toBe(0);
    expect(component.loading).toBeFalsy();
  });
}

I'm trying to test to see if some value gets set to 0 with the following code and test:

Code:

this.customShell.customShellApp.element.nativeElement.scrollTop = 0;

Test:

spyOnProperty(component.customShellApp, 'element', 'set').and.returnValue({
  nativeElement: { scrollTop: 0 }
});
expect(component.customShellApp.element.nativeElement.scrollTop).toBe(0);

But I'm getting the following error:

Error: <spyOnProperty> : spyOn could not find an object to spy upon for element

Anybody know how I can test the full property? The property comes from a CustomShellBase which we extend.

Full code below:

AppComponent.ts

import { Component, Injector, OnDestroy } from '@angular/core';
import { Event, NavigationEnd, Router } from '@angular/router';
import { Subject } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
import { CustomShellBase, CustomShellService } from 'custom-shell-angular';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html'
})
export class AppComponent extends CustomShellBase implements OnDestroy {
  loading = false;

  protected destroyed$: Subject<boolean> = new Subject();

  constructor(
    protected injector: Injector,
    private router: Router,
    protected shellService: CustomShellService
  ) {
    super(injector);

    this.router.events
      .pipe(takeUntil(this.destroyed$))
      .subscribe((event: Event) => {
        if (event instanceof NavigationEnd) {
          this.customShell.customShellApp.element.nativeElement.scrollTop = 0;
          this.loading = false;
        }
      });
  }

  ngOnDestroy(): void {
    this.destroyed$.next(true);
    this.destroyed$.complete();
  }
}

AppComponent.spec.ts

describe('AppComponent', () => {
  let component: AppComponent;
  let fixture: ComponentFixture<AppComponent>;

  let shellNavService: CustomShellNavService;
  let router: Router;

  const eventSubject = new ReplaySubject<RouterEvent>(1);
  const routerMock = {
    navigate: jasmine.createSpy('navigate'),
    events: eventSubject.asObservable(),
    url: 'test/url'
  };
  
  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [AppComponent],
      providers: [
        CustomShellService,
        { provide: CustomShellNavService, useClass: MockCustomShellNavService },
        { provide: Router, useValue: routerMock },
      ],
      imports: [
        RouterTestingModule.withRoutes(routes)
      ],
      schemas: [CUSTOM_ELEMENTS_SCHEMA]
    });

    fixture = TestBed.createComponent(AppComponent);
    component = fixture.componentInstance;

    shellNavService = TestBed.inject(CustomShellNavService);
    router = TestBed.inject(Router);
  });

  it('should set the loading on FALSE and scroll to the top when a NavigationEnd event happens', () => {
    eventSubject.next(new NavigationEnd(1, '', ''));
    spyOnProperty(component.customShellApp, 'element', 'set').and.returnValue({
      nativeElement: { scrollTop: 0 }
    });
    expect(component.customShellApp.element.nativeElement.scrollTop).toBe(0);
    expect(component.loading).toBeFalsy();
  });
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

网白 2025-01-16 07:50:22

尝试直接更改customShellApp的属性而不是使用spyOnProperty

it('should set the loading on FALSE and scroll to the top when a NavigationEnd event happens', () => {
    // this should be mocked before the eventSubject.next
    (component as any).customShellApp = {
      element: {
        nativeElement: {
          scrollTop: 0
        }
      }
    };
    eventSubject.next(new NavigationEnd(1, '', ''));
    expect(component.customShellApp.element.nativeElement.scrollTop).toBe(0);
    expect(component.loading).toBeFalsy();
  });

如果customShellApp是私有的,则可能很难断言

Try to directly change the property of customShellApp instead of using spyOnProperty

it('should set the loading on FALSE and scroll to the top when a NavigationEnd event happens', () => {
    // this should be mocked before the eventSubject.next
    (component as any).customShellApp = {
      element: {
        nativeElement: {
          scrollTop: 0
        }
      }
    };
    eventSubject.next(new NavigationEnd(1, '', ''));
    expect(component.customShellApp.element.nativeElement.scrollTop).toBe(0);
    expect(component.loading).toBeFalsy();
  });

If customShellApp is private, it can be difficult to assert

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文