单元测试 typescript 指令模板 karma-jasmine,html 未定义

Posted

技术标签:

【中文标题】单元测试 typescript 指令模板 karma-jasmine,html 未定义【英文标题】:unit testing typescript directive template karma-jasmine, html is not defined 【发布时间】:2016-06-24 01:04:35 【问题描述】:

最近我开始使用 karma-jasmine 对我的 typescript 代码进行单元测试。在为服务和一个简单指令创建并运行测试用例后,我为自定义指令创建了一个测试用例,它有一个控制器(正在注入一项服务)并使用 4 个范围变量与外界通信。

这是一个简单的单元测试用例来检查指令是否正在渲染它的模板。

在运行这个单元测试用例时,业力会抛出一些错误

09 03 2016 19:59:27.056:INFO [framework.browserify]: bundle built
09 03 2016 19:59:27.063:INFO [karma]: Karma v0.13.21 server started at http://localhost:9876/
09 03 2016 19:59:29.964:INFO [Chrome 49.0.2623 (Linux 0.0.0)]: Connected on socket /#4OCi116hP6TDqCsmAAAA with id manual-1348
LOG: Object0: <normal-directive></normal-directive>, length: 1
Chrome 49.0.2623 (Linux 0.0.0) normal should render the template FAILED
Error: [$injector:unpr] Unknown provider: FacadeServiceProvider <- FacadeService
http://errors.angularjs.org/1.5.0/$injector/unpr?p0=FacadeServiceProvider%20%3C-%20FacadeService

//some reference to file
TypeError: Cannot read property 'html' of undefined
    at Object.<anonymous> (/tmp/5c59a59c62f48798a123b52b0468515b.browserify:476:23

在调试它时,我知道它正在将“正常指令”视为普通文本而不是 html 标记。

normal-directive.spec.ts

import appName from '../../../../main';
import NormalController from '../../../../components/normalManager/normalList/NormalController';

describe('normalManager.normalList', () => 
    let $compile:angular.ICompileService,
        $rootScope:any,
        template:angular.IAugmentedJQuery,
        element:angular.IAugmentedJQuery,
        controller:NormalController,
        controllerSpy:jasmine.Spy;

    beforeEach(() => 
        angular.mock.module(appName);

        inject((_$compile_:ng.ICompileService, _$rootScope_:ng.IRootScopeService) => 
            $compile = _$compile_;
            $rootScope = _$rootScope_;
        );

        template = angular.element('<div normal-directive></div>');
        element = $compile(template)($rootScope);//getting error on this line.
        controller = element.controller('normalList');

        $rootScope.$digest();
    );

    it('should render the component', () => 
        expect(element.html()).toContain('<!-- normalManager.normalList -->');
    );
);

normal-directive.ts

import * as angular from 'angular';
import normalController from './normalController';
import html from './normal.html'

module normal 
    "use strict";
    export class normal 
        public link: (scope: ng.IScope, element: ng.IAugmentedJQuery, attrs: ng.IAttributes) => void;
        public template = html;
        public scope = 
            ngNormalVariables: '=',
            ngNormalData: '=',
            ngDifferentType: '=',
            ngType: '='
        ;
        public restrict: string = 'EA';
        public controller =  normalController;
        public controllerAs: string =  'vm';
        public bindToController:boolean =  true;

        constructor() 
            normal.prototype.link = (scope: ng.IScope, element: ng.IAugmentedJQuery, attrs: ng.IAttributes) => 

            ;
        

        public static Factory() 
            var directive = () => 
                return new normal();
            ;

            directive['$inject'] = [];
            return directive;
        
    


export default normal;

normalController.ts

import IfcNormalFacadeService from '../../../normal_core/services/NormalFacadeService/IfcNormalFacadeService'
export class normalController 
    //Variable injection
    private normalFacadeService: IfcNormalFacadeService;

    public xVariableVal = null;
    public yVariableVal = null;

    //Scope variables
    private ngNormalData = x:null, y:null, t:null, z:null;
    private ngNormalVariables = x: [], y:[], t:[], z:[];
    private ngType = null;
    private ngDifferentType = null;

    constructor(normalFacadeService: IfcNormalFacadeService) 
        console.log("Inside Normal controller");
        this.normalFacadeService = normalFacadeService;
    

    ....//Remaining code

我正在参考this repo 来编写测试用例和打字稿自定义指令代码。

如果您需要更多信息,请告诉我。如果您知道任何具体的博客/网站以了解有关打字稿的 karma-jasmine 单元测试的更多信息,请告诉我。

感谢您抽出宝贵的时间阅读。

问候

阿杰

【问题讨论】:

【参考方案1】:

我需要为 facadeService 做一个模拟。

演示 mocks.ts

import IfcFacadeService from 'filePath'

export const facadeServiceMock: IfcFacadeService 

    methodName: (): any => ; 


要使用这个模拟,请导入它

演示 .html.spec.ts

import facadeServiceMock from 'mockPathName'

beforeEach(()=>
angular.mock.module(appName), FacadeService: facadeServiceMock);
)

【讨论】:

以上是关于单元测试 typescript 指令模板 karma-jasmine,html 未定义的主要内容,如果未能解决你的问题,请参考以下文章

无法从 Typescript 类中的角度指令加载模板(404)

Angular 指令单元测试:$templateCache 还是 $httpBackend?

angular 调试 js (分 karms protractor / test e2e unit )

是否可以像我们在 Angular 2 中测试属性指令一样对结构指令进行单元测试

TypeScript 中的单元测试 [关闭]

在 Typescript 单元测试中模拟