angular - 如何使用 karma+jasmine 测试 Angular 2 中的位置

标签 angular karma-jasmine

Angular 2 v.2.0.0 - TS + karma + Jasmine 。

我测试了这个功能 - 单击返回上一页:

 public isClick: boolean = false;

 public backClicked(location: Location): void {
        if (!this.isClick) {
            this.isClick = true;
            this.location.back();
        }
    }

这是我的测试:

describe("NavBarComponent", () => {
    describe("function backClicked(): void", () => {
        let testNavBarComponent: NavBarComponent;
        let loc: Location;
        beforeEach(() => {
            testNavBarComponent = new NavBarComponent(null);
        });
        loc = jasmine.createSpyObj("Location", ["back"]);
        it ("It is backClicked() function test", () => {
            testNavBarComponent.backClicked(loc);
            expect(loc.back).toHaveBeenCalledTimes(1);
        });
    });
});

运行测试后,出现此错误:TypeError: Cannot read property 'back' of null。也许是 createSpyObj 或其他问题有问题?

最佳答案

在 backClicked 函数中,您调用的是 location this.location 的类实例,而不是传递给函数 location 的 location 实例。我假设您的 NavBarComponent 由于错误消息而注入(inject)了 Location(默认情况下,事物是未定义的而不是 null)。

您可以执行以下操作:

beforeEach(() => {
    // Mock the location here instead, then pass to the NavBarComponent
    loc = jasmine.createSpyObj("Location", ["back"]);
    testNavBarComponent = new NavBarComponent(loc);
});
<小时/>

或者,我很幸运地使用了 Angular 的 ReflectiveInjector类(class)。可用于在 Angular 2 中模拟测试依赖项的文档和文章完全来自于 RC 的多次迭代,所以我不能 100% 确定这被认为是最佳实践:

import { ReflectiveInjector } from '@angular/core';
import { Location } from '@angular/common';

describe("NavBarComponent", () => {
    describe("function backClicked(): void", () => {
        let testNavBarComponent: NavBarComponent;
        let loc: Location;

        beforeEach(() => {
            let injector = ReflectiveInjector.resolveAndCreate([
                LocationStrategy,
                Location
            ]);

            // Get the created object from the injector
            loc = injector.get(Location);

            // Create the spy.  Optionally: .and.callFake(implementation)
            spyOn(loc, 'back');

            // Create NavBarComponent with the spied Location
            testNavBarComponent = new NavBarComponent(loc);
        });

        it ("It is backClicked() function test", () => {
            testNavBarComponent.backClicked(loc);
            expect(loc.back).toHaveBeenCalledTimes(1);
        });
    });
});

编辑:这可以而且应该现在使用 TestBed.configureTestingModule 来完成:https://blog.thoughtram.io/angular/2016/11/28/testing-services-with-http-in-angular-2.html

使用 ReflectiveInjector,您还可以像在 app.module 中一样声明依赖项。例如,模拟Http服务:

let injector = ReflectiveInjector.resolveAndCreate([
    MockBackend
    BaseRequestOptions,
    {
        provide: Http,
        useFactory: (backend, options) => {
            return new Http(backend, options);
        },
        deps: [MockBackend, BaseRequestOptions]
    }
]);

关于angular - 如何使用 karma+jasmine 测试 Angular 2 中的位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41982166/

相关文章:

带有 Material 选项卡的 Angular 8 - 在重新加载时选择最后一个事件选项卡

angular - 当验证器设置为 minLength 时空字段控制有效

angular 2 - 如何设置 <select> 默认选择选项

forms - Angular 2 新表单,提交时重定向到同一页面,表单字段附加在 URL 中作为具有新路由器版本的查询参数

javascript - 使用 Jasmine 2 测试 Promise.then

angular - 我可以使用指定的种子运行 Karma 测试吗?

javascript - 如何在单次运行期间使用 karma test-runner 测试两个具有相同名称的不同类?

html - Angular 和数据列表

javascript - Karma 中的另一个 'module is not defined'

angular - 如何使用模拟 websocket 来测试服务功能中的 onMessage?