Jasmine:如何模拟MutationObserver?

11 javascript jasmine angularjs mutation-observers karma-jasmine

我有一个angularjs组件,

HTML模板

<div id="panel" class="hide-div">
   <div id="viewPort" class="hide-div">
    ...
   </div>
</div>
Run Code Online (Sandbox Code Playgroud)

JS

var myController = function() {
    var ctrl=this;
    ctrl.$onchanges = function() {

    }

    var source = $("#viewport");
    var target = $("#panel");
    var observer = new MutationObserver(function() {
       target.toggleClass("hide-div", source.hasClass("hide-div"));
     });
    observer.observe($("#viewport")[0], {attributes: true});
}

var config = {
    controller: [myController],
    templateUrl: "temp/abc.html",
    bindings: {
        id: "<",
        name: "<"
    }
};

directives.component("myComponent", config);
Run Code Online (Sandbox Code Playgroud)

在这里,我MutationObserver通过观察其他元素属性来添加/删除类

Jasmine脚本 我在这里设置所有测试用例的脚本

beforeEach(inject(function($rootScope,  $compile, _$componentController_, ...){
    $templateCache.put("temp/abc.html", "<div><div id='panel' /><div id='viewport' /></div>");
    rootScope = $rootScope;
    scope = $rootScope.$new();
    $componentController = _$componentController_;
    element = angular.element("<my-component></my-component>");
    element = $compile(element)(scope);
    ctrl = $componentController("myComponent", null, componentBining);
}));
Run Code Online (Sandbox Code Playgroud)

这里我收到以下错误,

NotFoundError: NotFoundError: DOM Exception 8 in temp/abc.html observe@[native code]

Evg*_*man 1

JSDom 全局变量与您所期望的不同。

这个问题的答案得把焦点从“如何mock MutationObserver?”转移过来。到“为什么首先要嘲笑它?”

MutationObserver 是在外部为您实现的,希望它能够正常工作。所以我不会将其作为我的测试范围的一部分进行测试。相反,我只是提取回调

const triggerHandler = function() {
       target.toggleClass("hide-div", source.hasClass("hide-div"));
     }

 var observer = new MutationObserver(triggerHandler);
Run Code Online (Sandbox Code Playgroud)

并手动触发handler来测试效果。

另外,您可以使用 来模拟 MutationObserver jest.fn(),例如

global.MutationObserver = jest.fn(()=>{
  return {...}
})
Run Code Online (Sandbox Code Playgroud)