【问题标题】:How to test the existence of a Lazy Loaded route in Angular?如何测试 Angular 中是否存在延迟加载的路由?
【发布时间】:2020-10-09 11:29:01
【问题描述】:

我的问题类似于this question。我正在尝试编写一个测试来检查 Angular 中是否存在路由。与链接问题的主要区别在于,我使用的是延迟加载模块而不是组件。

我有一个包含路由的文件 app.routes.ts

import { Routes } from '@angular/router';

export const routes: Routes = [
    {
        path: '',
        loadChildren: () => import('./main/main.module').then(m => m.MainModule)
    }
];

在测试文件app.routes.spec.ts中,我希望这个路由存在:

import { routes } from './app.routes';

describe('app.routes', () => {
    it('should contain a route for /', () => {
        expect(routes).toContain({
            path: '',
            loadChildren: () => import('./main/main.module').then(m => m.MainModule)
        });
    });
});

当我运行它时,测试没有通过。

预期 [ Object({ path: '', loadChildren: Function }) ] 包含 对象({路径:'',loadChildren:函数})。错误:预期 [ Object({ path: '', loadChildren: Function }) ] 包含 Object({ 路径:'',loadChildren:函数})。 在 在用户上下文。 (http://localhost:9876/_karma_webpack_/src/app/app.routes.spec.ts:5:24) 在 ZoneDelegate.invoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-evergreen.js:365:1) 在 ProxyZoneSpec.onInvoke (http://localhost:9876/_karma_webpack_/node_modules/zone.js/dist/zone-testing.js:305:1)

如何修复这个单元测试,并确保可以测试延迟加载路由的存在?谢谢!

免责声明:我知道有些人不认为这应该是单元测试的一部分,并且应该在 e2e 测试中测试路由。就我个人而言,我喜欢检查我的所有路线是否存在并且没有拼写错误的想法。如果有人出于某种原因注释掉一条路线并忘记撤消它,而自动化测试会捕捉到这一点,这让我感觉更安全。

【问题讨论】:

  • 你检查下面的解决方案了吗?

标签: angular unit-testing


【解决方案1】:

根据 Aakash Garg 的回答,我找到了一个通用的解决方案来测试延迟加载的路由。 我正在分享我的解决方案,以防它可以帮助遇到同样问题的人。这个解决方案对我有用,但我并不是说这是做到这一点的完美方式。

基本上,我为 jasmine 添加了一个自定义匹配器来测试路由是否相等。

源代码文件equal-route-matcher.ts

import MatchersUtil = jasmine.MatchersUtil;
import CustomMatcherFactories = jasmine.CustomMatcherFactories;
import CustomEqualityTester = jasmine.CustomEqualityTester;
import CustomMatcher = jasmine.CustomMatcher;
import CustomMatcherResult = jasmine.CustomMatcherResult;

function replacer(key: any, value: any) {
    if (typeof value === 'function') {
        value = value.toString();
    }
    return value;
  }

export const EqualRouteMatcher: CustomMatcherFactories = {
    toEqualRoute: (util: MatchersUtil, customEqualityTester: CustomEqualityTester[]): CustomMatcher => {
        return {
            compare: (actual: any, expected: any): CustomMatcherResult => {
                let actualstring: string, expectedstring: string;
                actualstring = JSON.stringify(actual, replacer).replace(/(\\t|\\n)/g,'');
                expectedstring = JSON.stringify(expected, replacer).replace(/(\\t|\\n)/g,'');
                if (actualstring === expectedstring) {
                    return {
                        pass: true,
                        message: 'Routes are equal'
                    };
                } else {
                    return {
                        pass: false,
                        message: 'Expected route ' + actualstring + ' to equal route ' + expectedstring
                    };
                }
            }
        };
    }
};

类型定义文件equal-route-matcher-type.d.ts

declare namespace jasmine {
    interface Matchers<T> {
        toEqualRoute(expected: any, expectationFailOutput?: any): boolean;
    }
}

最后,您可以在单元测试文件中导入自定义匹配器,并像这样使用它:

import { routes } from './app.routes';
import { EqualRouteMatcher } from './equal-route-matcher.ts';

describe('app.routes', () => {
    beforeEach(() => {
        jasmine.addMatchers(EqualRouteMatcher);
    });

    it('should contain a route for /', () => {
      expect(routes.length).toEqual(1);
      expect(routes[0]).toEqualRoute({path: '',loadChildren: () => import('./main/main.module').then(m => m.MainModule)});
    });
});

【讨论】:

  • 它有点工作,但它并没有真正计入报道报告:(
【解决方案2】:

检查一下:-

    expect(routes.find((route) => JSON.stringify(route,function(key, value) {
  if (typeof value === "function") {
    return "/Function(" + value.toString() + ")/";
  }
  return value;
}) === JSON.stringify({"path":"","loadChildren":"/Function(() => import('./main/main.module').then(m => m.MainModule))/"}))).toBeTruthy();

它的工作截图:-

【讨论】:

  • 我使用这段代码时,最后一行出现编译错误。 import() 函数中的单括号破坏了字符串。当我在前面加上反斜杠时,代码编译,但测试没有通过。 “预期为假为真。”
  • 现在测试输出“Expected undefined to be truthy”。
  • 这意味着当我测试此路由时,您的配置中不存在该路由。
  • 尝试打印路线
  • 我发现了为什么这段代码对我不起作用。正在使用 Webpack,因此在我的情况下字符串如下: /Function(() => webpack_require.e(/*! import() / 0).then(webpack_require.bind(null, /!./main/main.module */ "./src/app/main/main.module.ts")).then(m => m.MainModule))/ 我希望有一个不那么基于字符串比较的解决方案
猜你喜欢
  • 1970-01-01
  • 2017-05-17
  • 1970-01-01
  • 1970-01-01
  • 2020-06-01
  • 2022-11-11
  • 1970-01-01
  • 2017-04-08
  • 2019-01-13
相关资源
最近更新 更多