用于单元测试角度路由器和 CanActivate 防护的最小模拟 [英] Minimal mock for unit testing angular Router and CanActivate guard

查看:22
本文介绍了用于单元测试角度路由器和 CanActivate 防护的最小模拟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

import {Router, ActivatedRouteSnapshot, RouterStateSnapshot, UrlTree} from '@angular/router';

@Injectable({provideIn: 'root'})
export class FooGuard implements CanActivate {
  constructor (private readonly router: Router) {}

  canActivate (next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<UrlTree> {
    const xxx = myMagic(next); // irrelevant app logic that depends on next url only

    return (async () => this.router.parseUrl(xxx));
  }
}

试图找到一个没有额外样板页面的测试代码示例.希望每个模拟可以得到接近 5-6 行代码的东西.需要:

Trying to find an example of testing code for this piece without a page of extra boilerplate. Hopefully can get something closer to 5-6 lines of code per mock. Need:

  • 模拟Router
  • 模拟 ActivatedSnapshot

推荐答案

看一看 RouterTestingModule.这不是一个六行代码的解决方案,而是一个非常紧凑的解决方案.我认为这是测试守卫和路线的最佳方式:

Take a look at RouterTestingModule. It's not a six lines of code solution, but a pretty compact one. I think it's the best way to test guards and routes:

import { Component, Injectable } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot, UrlTree } from "@angular/router";
import { RouterTestingModule } from '@angular/router/testing';

@Injectable({
    providedIn: 'root'
})
export class FooGuard implements CanActivate {
    constructor (private readonly router: Router) {}

    canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): UrlTree {
      const url = "some/new/url"; // create an url based on next snapshot
      return this.router.parseUrl(url);
    }
  }

@Component({ template: '' })
export class DummyComponent {}

function setup(): {
    router: Router
} {
    TestBed.configureTestingModule({
        imports: [
            RouterTestingModule.withRoutes([
                { path: 'test', component: DummyComponent, canActivate: [ FooGuard ] },
                { path: 'some/new/url', component: DummyComponent }
            ])
        ],
        declarations: [
            DummyComponent
        ]
    });

    return {
        router: TestBed.get(Router)
    };
}

describe(FooGuard.name, () => {
    it('should redirect to a new url', async () => {
        const { router } = setup();
        await router.navigateByUrl('/test');
        expect(router.url).toBe('/some/new/url');
    })
});

<小时>

实际上常规的Router.forRoot() 也应该适用于这种情况,但是RouterTestingModule 必须更适合测试.例如,最后一个提供 custom Location 实现.


Actually the regular Router.forRoot() should also work in this case, but RouterTestingModule must be more suitable for testing. For example the last one provides custom Location implementation.

这篇关于用于单元测试角度路由器和 CanActivate 防护的最小模拟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆