角度测试 - 使用$ emit从根范围触发事件

时间:2015-11-13 04:02:40

标签: angularjs unit-testing testing angularjs-scope jasmine

我正在尝试测试正在调用服务的控制器。当此服务完成其工作时,它将使用$ emit从根范围调度事件。我试图在我的测试中模拟这个,但我无法让事件处理程序运行。谁能看到我做错了什么?

这是我测试的基本版本:

Files = Mocks.Files;

beforeEach(inject(function($rootScope, $controller) {
    scope = $rootScope.$new();
    $controller("HelpController", { $scope: scope });   // inherit scope from parent

    rootScope = $rootScope.$new(); 
    rootScope.profile = {
        ....
    };

    $controller("HelpContentEditorController", {
        $scope: scope,
        $rootScope: rootScope
        Files: Files
    });

    scope.$apply();
}));

it("should save FileResource to API", function() {
        spyOn(Files, "saveFileAPI");
        scope.saveContent();
        scope.$apply();
        rootScope.$emit("allFilesUploaded", []);
        rootScope.$apply();

        expect(Files.saveFileAPI).toHaveBeenCalled();
    });

然后在我正在测试的控制器内部

function saveContent() {
    var blob = new $window.Blob([JSON.stringify($scope.content)], {type: "text/json"});
    blob.name = "help.json";

    $rootScope.$on("allFilesUploaded", onFilesUploaded);
    Files.upload([blob]);
}

function onFilesUploaded(event, files) {
    Files.saveFileAPI(files[0], files[0].extensions[0]).then(function(data) {
        ...
    }, function (error) {
        ...
    });
}

测试运行没有错误,但是从不调用onFilesUploaded方法,因此它失败了。我不确定这是否与我继承范围等方面有关,但我尝试了一些替代方案

谢谢!

1 个答案:

答案 0 :(得分:1)

可能有助于澄清您的测试正在做什么:

在您的beforeEach部分中,您创建scope = $ rootScope。$ new()和rootScope = $ rootScope。$ new()。这样,scope和rootScope就是兄弟姐妹。两者都是$ rootScope的子节点,并且它们之间没有正如名称所示的父子关系。(如果你想让rootScope成为实际且唯一的rootScope,而不仅仅是使用rootScope = $ rootScope)。

比看看你的$ emit:你提供一个空的Array []作为附加参数但是在你的事件处理程序中你期望至少有一个元素文件[0]并在Files.saveFileApi中使用它作为参数(files [0] ...)

据我所知,您的eventHandler将被调用但崩溃。