Jasmine测试用例错误'间谍被称为'

时间:2015-07-26 07:58:55

标签: javascript angularjs jasmine karma-jasmine

我正在为下面的角度函数编写茉莉花测试用例并且获得测试用例失败消息“预期的间谍[对象对象]被调用”。

    $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);
            });
        });
    };

我的茉莉花测试案例

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();

});

得到以下错误 “已经调用了预期的间谍[对象]。 错误:已调用期望的间谍[对象]。“

我的测试用例中有什么问题?我错过了什么吗?

提前致谢!!!

编辑: 更改了我的Jasmine测试用例如下所示获取不同的消息''undefined'不是一个函数(评估'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();

});

1 个答案:

答案 0 :(得分:2)

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

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

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

要检查间谍是否被调用,您应该将其传递给expect()

expect(modalDialogFactory.showDialog).toHaveBeenCalled();

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

<强>更新

第一个代码段中有一行:

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

正如您所见,showDialog()后跟then()。我假设原始showDialog()使用方法then()返回一些对象,也许它是一个Promise。但是在您进行showDialog()方法监视的测试中,从callFake()开始,您不会使用then()方法返回任何内容,因此错误表明方法未定义。间谍完全取代了原始方法,并与callFake()一起重新创建原始行为。

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

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

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