【问题标题】:How to unit test an observable with jasmine如何使用 jasmine 对 observable 进行单元测试
【发布时间】:2017-08-13 09:16:51
【问题描述】:

我在构造函数中添加了一些代码,现在我的单元测试失败了。新代码从 observable 将 true 或 false 设置为 this.isFollowOnMode

import { CustomerGroupService } from 'customerGroup.service';

class HeaderBarController {
    private isFollowOnMode: boolean;

    constructor(private customerGroupService: CustomerGroupService) {
        'ngInject';

        //new code that is causing test to fail:

        this.customerGroupService.isFollowOnMode$ // will be true or false
            .subscribe((isFollowOnMode) => {
                this.isFollowOnMode = isFollowOnMode;
            });
    }

    // other stuff
}

export default HeaderBarController;

我在单元测试中收到以下错误:

PhantomJS 2.1.1 (Mac OS X 0.0.0) 控制器:应该定义 HeaderBarController FAILED TypeError: undefined is not a constructor (evalating 'this.customerGroupService.isFollowOnMode$'

这是我失败的单元测试:

describe('Controller: HeaderBarController', function () {
    beforeEach(angular.mock.module(module.name));

    beforeEach(angular.mock.module(function ($provide) {
        $provide.service('customerGroupService', () => { });

    }));

    beforeEach(inject(function ($rootScope, $componentController) {
        this.$scope = $rootScope.$new();
        this.ctrl = $componentController('headerBar',
            {
                // locals
                $scope: this.$scope,
                $element: [{}],
                $attrs: [],
            },
            {
                // scope bindings
            }
        );
    }));

    it('should be defined', function () {
        expect(this.ctrl).toBeDefined();
    });

});

看来我没有设置this.customerGroupService.isFollowOnMode$。它的默认值应该是 false。在单元测试中。我是单元测试新手。

【问题讨论】:

  • 只是备注,除非事情发生了变化,否则 TypeScript/ESNext 源代码中的'ngInject' 被认为是不可靠的。交替写class HeaderBarController {static $inject = ['customerGroupService'];会更健壮,你可以使用装饰器自动创建注释。

标签: angular typescript jasmine


【解决方案1】:

此问题并非特定于可观察对象,而是一般适用于服务存根。

这个

$provide.service('customerGroupService', () => {});

将导致服务没有预期的属性,使用箭头代替构造函数也是不正确的。

ngMock 已经提供了一种模拟服务的方法:

let customerGroupServiceMock;

beforeEach(() => {
  customerGroupServiceMock = {
    isFollowOnMode$: Observable.of(true);
  };
  angular.mock.module({ customerGroupService: customerGroupServiceMock });
});

也可以直接将模拟服务注入控制器,而不是在注入器中定义它们:

    this.ctrl = $componentController('headerBar',
        {
            // locals
            customerGroupService: customerGroupServiceMock,
            $scope: this.$scope,
            $element: [{}],
            $attrs: [],
        },

这正是“本地人”的意思。

【讨论】:

    猜你喜欢
    • 2021-01-28
    • 2017-02-28
    • 2014-08-15
    • 1970-01-01
    • 1970-01-01
    • 2019-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多