Unit Test - $componentController

Angular1.5+ 的component语法很赞, 但是对它们做单元测试时难住了我.

指令的测试向来比较繁琐, 需要$compile拿到element, 在通过element得到controller.

beforeEach(angular.mock.inject($injector => {
    $compile = $injector.get('$compile');
    $rootScope = $injector.get('$rootScope');
    scope = $rootScope.$new();
    element = $compile(`
        <input name="tel" ng-model="tel" type="tel"/>
    `)(scope);
    $rootScope.$apply();
    controller = element.controller('ngModel');
}));

虽然component是directive的语法糖, 但是它的测试却有点不太一样, 在component doc 中提到了一个$componentController服务, 它包含在ngMock中, 这个服务的优点在于你可以不用创建DOM元素就能测试controller.

Component测试实例

假设有如下Component

export const FormRenderComponent = {
    template,
    controller,
    bindings: {
        data:   '<',
        name:   '@',
        onSave: '&'
    }
};

---Magic Is Here---

为了拿到该组件的控制器, 代码非常简单.

let $componentController, controller;
let bindings = {
    data:   [],
    name:   'form name',
    onSave: angular.noop
};
beforeEach(angular.mock.inject($injector => {
    $componentController = $injector.get('$componentController');
    controller = $componentController('formRender', null, bindings);
}));

$componentController的第一个参数就是需要测试的组件名, 通过.component注册在模块上的, 第二个参数是locals可以用来提供$scope, $attr, $element, 第三个参数是bindings的值. 如需更详细的描述请查阅官方文档. 如果你locals几个对象全用上了, 变得很复杂, 建议还是用$compile的方式拿controller.

.component('formRender', FormRenderComponent)

测试代码就就随意发挥了, 举个简单的例子, 测试bindings的数据是否赋值成功.

it('bindings should work', () => {
    expect(controller.data).toEqual(bindings.data);
    expect(controller.name).toEqual(bindings.name);
});

不要忘了$onInit()

如果你的组件实现了$onInit生命周期函数, 进行测试的时候必须确保手动调用, $ 否则不会触发.

it('$onInit() should init data and events', () => {
    spyOn(controller, 'initData');
    spyOn(controller, 'initEvents');
    controller.$onInit();
    expect(controller.initData).toHaveBeenCalled();
    expect(controller.initEvents).toHaveBeenCalled();
});

为了代码的质量和可读性, 单元测试是必须的, 如果你还没有养成写单元测试的习惯, 那就从现在开始吧.

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,324评论 19 139
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 175,173评论 25 709
  • 文章作者:Tyan博客:noahsnail.com 3.4 Dependencies A typical ente...
    SnailTyan阅读 9,716评论 2 7
  • Angular面试题 一、ng-show/ng-hide与ng-if的区别? 第一点区别是,ng-if在后面表达式...
    w_zhuan阅读 10,886评论 0 26
  • 这两天懒惰的什么都不想做。感赏也没写。 看到群里赵芳对家长耐心的引导,层层提问,抽丝剥茧剖析挖掘最深处的原因。两天...
    小石印儿阅读 2,350评论 0 7