0

我需要帮助才能为router.events.subscribe. 我曾经ActivationEnd使用具有应用程序所需属性的快照对象。路由器没有其他事件提供这些,所以我必须坚持这一点ActivationEnd。但是我没有得到任何关于如何模拟这个快照对象的信息。

下面是我的代码片段。

ngOnInit() {
    this.router.events.subscribe(e => {
      if (e instanceof ActivationEnd) {
        this.section = e.snapshot.data.title;
        this.dynamicSubNavLabel = e.snapshot.routeConfig?.data?.label;
      }
    });
  }

你能帮我做些什么来实现这个或任何替代方案的单元测试吗?

问候, 阿尔佩什

4

2 回答 2

0

我有时会混合使用 jasmine.createSpyObj 和 json 对象,也许这会对您有所帮助:

 const activationEndMock = {
    ...jasmine.createSpyObj(['']),
    snapshot: {
      data: {
        title: 'a title'
      },
      routeConfig: {
        data: {
          label: 'a label'
        }
      }
    }
  }
  const routerMock = {
    ...jasmine.createSpyObj<Router>(['']),
    events: of(activationEndMock)
  };

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [RouterTestingModule],
      providers: [{ provide: Router, useValue: routerMock }]
    });
    .........
  });

我不确定这会起作用,因为我没有测试它。

于 2021-09-07T08:24:19.130 回答
0

假设你有一个这样的组件:

import { Component, OnInit } from '@angular/core';
import { ActivationEnd, Router } from '@angular/router';

@Component({
  selector: 'app-test-router',
  templateUrl: './test-router.component.html',
  styleUrls: ['./test-router.component.css']
})
export class TestRouterComponent implements OnInit {
  section = '';
  dynamicSubNavLabel = '';
  constructor(private router: Router) { }

  ngOnInit() {
    this.router.events.subscribe(e => {
      if (e instanceof ActivationEnd) {
        this.section = e.snapshot.data.title;
        this.dynamicSubNavLabel = e.snapshot.routeConfig?.data?.label;
      }
    });
  }

}

因为已经Router.eventsSubject<Event>。我们可以完成这个:

  • 我们将它转​​换为Subject<Event>然后调用next以发出我们的自定义/模拟 ActivationEnd 事件。
  • 首先将我们的模拟数据转换为 unknown,然后再转换为 ActivatedRouteSnapshot。
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ActivatedRouteSnapshot, ActivationEnd, Event, Router } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { Subject } from 'rxjs';

import { TestRouterComponent } from './test-router.component';

describe('TestRouterComponent', () => {
  let component: TestRouterComponent;
  let fixture: ComponentFixture<TestRouterComponent>;
  let router: Router;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [RouterTestingModule],
      declarations: [ TestRouterComponent ]
    })
    .compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(TestRouterComponent);
    component = fixture.componentInstance;
    router = TestBed.inject(Router);
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should update data from router', () => {
    const events$ = router.events as Subject<Event>;
    const mockSnapshot = {
      data: {
        title: 'some heading'
      },
      routeConfig: {
        data: {
          label: 'some text'
        }
      }
    } as unknown as ActivatedRouteSnapshot;
    events$.next(new ActivationEnd(mockSnapshot));
    expect(component.section).toBeTruthy();
    expect(component.dynamicSubNavLabel).toBeTruthy();
  })
});

来自 Angular 的源代码:https ://github.com/angular/angular/blob/75a3c778b1f7be913f0287423d40fade68ee9adc/packages/router/src/router.ts#L461

于 2021-09-12T10:27:27.700 回答