【问题标题】:Awaiting Angular router navigation in Jasmine等待 Jasmine 中的 Angular 路由器导航
【发布时间】:2021-07-06 10:10:37
【问题描述】:

假设我有一个代码片段来测试:

  • Navigates(只是为了去掉一个查询字符串参数)
  • Then,执行 HTTP 调用

我想用HTTP测试控制器来匹配对应的请求。

下面的代码显然不行

service.doStuff();
httpController.expectOne(...);

我尝试订阅 Angular 路由器的事件,但没有成功

router.events.subscribe(event => {
    if (event instanceof NavigationEnd) { // last event emitted
        httpController.expectOne(...); // still too early
    }
});

基本上我的测试失败了,因为我的期望太早比真正的http调用(我可以调试,router.navigate返回承诺)。

来自doStuff的代码

  from(this.router.navigate([], {
    relativeTo: this.activatedRoute,
    queryParams: {
      token: null
    },
    queryParamsHandling: 'merge'
  }))
    .pipe(switchMap(() => this.doRemotely()))
    .subscribe(result => {
      .....
    });
}

导航承诺返回后doRemotely被正确激活,但我无法拦截。

我正在考虑模拟路由器...关于在发出 HTTP 调用之后运行期望的正确方法有什么想法吗?

[编辑] 在 Jasmine 间谍上使用 callFake 不太可能解决我的问题,因为在虚假承诺返回后我无法做出预期。然而,模拟路由器有助于隔离测试。

【问题讨论】:

  • 您是否使用真正的路由器进行测试?
  • 不,RouterTestingModule 带有 provided ActivatedRoute
  • 您如何处理测试中的异步?
  • 我的意思是你使用 fakeAsync 还是异步等待
  • 我没有在问题中提到done 函数,但我的想法是1)订阅正确的事件和2)在期望得到满足后发出done 函数。问题是测试失败是因为期望没有得到满足。我通过调试发现 NavigationEnd 事件是在 promise 返回之前发出的,所以在被测单元之前switchMap。被测单元目前没有发布事件来告诉我可以订阅的“嘿,我已经完成了一个 http 调用”

标签: angular unit-testing jasmine


【解决方案1】:

在测试中使用真实路线是一件棘手的事情。但是,您可以尝试执行类似于 https://ng-mocks.sudo.eu/guides/route 的操作,以正确初始化测试中的路由:

describe('TestRoute:Route', () => {
  beforeEach(() => TestBed.configureTestingModule({
    // Providing a route testing module is important
    imports: [RouterTestingModule.withRoutes([
      // routes
    ])],
  }).compileComponents());

  // fakeAsync is important
  it('renders', fakeAsync(() => {
    const fixture = TestBed.createComponent(RouterOutlet);
    const router: Router = TestBed.inject(Router);
    const location: Location = TestBed.inject(Location);

    // First we need to initialize navigation.
    location.go('/1');
    if (fixture.ngZone) {
      fixture.ngZone.run(() => router.initialNavigation());
      tick(); // is needed for rendering of the current route.
    }

    // We should land to the desired route.
    expect(location.path()).toEqual('/1');
  }));
});

【讨论】:

  • TestBed.get() 现在已弃用。 :(
  • 嗨。您可以改用 TestBed.inject()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-05-05
  • 1970-01-01
  • 2017-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多