javascript - Jasmine 测试用例错误 'Spy to have been called'

标签 javascript angularjs jasmine karma-jasmine

我正在为下面的 Angular 函数编写 jasmine 测试用例,并收到测试用例失败消息“Expected spy [object Object] to have been called”。

    $scope.displayTagModelPopup = function() {
        var dialogOptions = {
            templateUrl: 'views/mytags.html',
            controller: 'TagsCtrl',
            size: 'lg',
            resolve: {
                tagsAvailable: function() {
                    return $scope.availableTags;
                }
            }
        };

        ModalDialogFactory.showDialog(dialogOptions).then(function(result) {
            $scope.selectedFields = [];
            $scope.selectedFieldIds = [];

            angular.forEach(result, function(tag) {
                $scope.selectedFields.push(tag);
                $scope.selectedFieldIds.push(tag.objectId);
            });
        });
    };

我的 Jasmine 测试用例

it('should call displayTagModelPopup', function() {
    var dialogOptions = {
        templateUrl: 'views/mytags.html',
        controller: 'TagsCtrl',
        size: 'lg',
        tagsAvailable: [{
            objectId: "c647abc7-f651-4df6-880d-cf9fb69cdcb0",
            dataFieldName: "author",
            shortNamePath: "$.author",
            templates: ["HaM sheet"]
        }]
    };
    var spy = jasmine.createSpy(modalDialogFactory, 'showDialog').and.callFake(function(data) {
        $scope.tags = [{
            objectId: "c647abc7-f651-4df6-880d-cf9fb69cdcb0",
            dataFieldName: "author",
            shortNamePath: "$.author",
            templates: ["HaM sheet"]
        }];
        return $scope.tags;
    });

    $scope.displayTagModelPopup();
    $scope.$digest();
    expect(spy).toHaveBeenCalled();

});

并得到以下错误 “预期 spy [object Object] 已被调用。 错误:预期已调用 spy [object Object]。”

我的测试用例中有什么问题?我是否遗漏了什么?

提前致谢!!!

已编辑: 更改了我的 Jasmine 测试用例,如下所示,得到不同的消息 ''undefined' is not a function (evaluating 'ModalDialogFactory.showDialog(dialogOptions).then')'

尝试是否定义了 ModelDialogFactory,但成功定义了 ModalDialogFactory.showDialog 方法。 仅当调用方法“$scope.displayTagModelPopup();”时获取测试用例失败

it('should call displayTagModelPopup', function() {

    spyOn(ModalDialogFactory, 'showDialog').and.callFake(function() {
        $scope.tags = [{
            objectId: "c647abc7-f651-4df6-880d-cf9fb69cdcb0",
            dataFieldName: "author",
            shortNamePath: "$.author",
            templates: ["HaM sheet"]
        }];
        return $scope.tags;
    });
    var dialogOptions = {
        templateUrl: 'views/mytags.html',
        controller: 'TagsCtrl',
        size: 'lg',
        tagsAvailable: [{
            objectId: "c647abc7-f651-4df6-880d-cf9fb69cdcb0",
            dataFieldName: "author",
            shortNamePath: "$.author",
            templates: ["HaM sheet"]
        }]
    };
    //expect(ModalDialogFactory).toBeDefined();
    //expect(ModalDialogFactory.showDialog).toBeDefined();

    $scope.displayTagModelPopup();
    $scope.$digest();

});

最佳答案

如果你想监视现有对象的方法,你应该使用 spyOn 帮助器(docs):

spyOn(modalDialogFactory, 'showDialog').and.callFake(...);

作为第一个参数,它应用一个对象,作为第二个 - 方法的名称。它用 spy 对象替换现有对象的方法。

要检查是否调用了 spy,你应该将它传递给 expect():

expect(modalDialogFactory.showDialog).toHaveBeenCalled();

您使用 jasmine.createSpy() 的助手是创建一个“裸” spy ,它可以作为回调传递以确保它被调用 ( docs )。 jasmine.createSpy() 只应用一个参数,即要在测试结果中显示的 spy 名称,这就是为什么没有任何 spy 附加到您的对象。


更新:

第一个片段中有一行:

ModalDialogFactory.showDialog(dialogOptions).then(function(result) { ... });

如您所见,showDialog() 后跟 then()。我假设原始 showDialog() 返回一些带有方法 then() 的对象,也许它是一个 Promise。但是在您的测试中,当您从 callFake() 监视 showDialog() 方法时,您不会使用 then() 方法返回任何内容,因此错误指出方法未定义。 Spy 完全替换了您的原始方法,并与 callFake() 结合使用,它重新创建了原始行为。

所以从 callFake() 你应该返回一些模仿 Promise 的东西,例如:

spyOn(ModalDialogFactory, 'showDialog').and.callFake(function() {
    // ....
    return {
        then: function (cb) {
             cb($scope.tags);
        }
    };
});

这里我返回一个对象,它有 then() 方法,当它被一个函数作为参数调用时,这个函数就像一个回调函数一样被 $scope 解析。 tags 值,可以在此回调中使用。

关于javascript - Jasmine 测试用例错误 'Spy to have been called',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31634863/

相关文章:

javascript - 如何使用jquery在父级上设置点击事件?

javascript - 如何使用 javascript 引用另一个页面元素

php - 如何在angularjs中显示单个数据库条目

JavaScript/jQuery getSelection 高亮合并span html元素

angular - 如何在 Angular Testing 中检索 ngClass 的值?

javascript - 停止正在执行的递归 javascript 函数

javascript - 在 Firefox 中替换选定的文本

angularjs - Chrome开发者工具中不显示cookie

javascript - 如何在 TypeScript 的监视模式下运行 Jasmine 测试

javascript - 我可以配置 gulp-jasmine 在浏览器中运行测试吗?