【问题标题】:Jasmine test case error 'Spy to have been called'Jasmine 测试用例错误“已调用间谍”
【发布时间】:2015-07-26 07:58:55
【问题描述】:

我正在为以下 angular 函数编写 jasmine 测试用例,并收到测试用例失败消息“预期的间谍 [object Object] 已被调用”。

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

});

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

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

提前致谢!!!

已编辑: 改变了我的 Jasmine 测试用例,如下所示,得到不同的消息 ''undefined' is not a function (evalating '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();

});

【问题讨论】:

    标签: javascript angularjs jasmine karma-jasmine


    【解决方案1】:

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

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

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

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

    expect(modalDialogFactory.showDialog).toHaveBeenCalled();
    

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


    更新:

    你在第一个sn-p中有一行:

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

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

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

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

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

    【讨论】:

    • 谢谢迈克尔!改变了我的测试用例,但没有运气。我不确定,但我怀疑我的 $scope.displayTagModelPopup() 方法没有与 ModalDialogFactory.showDialog 关联。如果您有时间,请查看我编辑的部分。
    猜你喜欢
    • 1970-01-01
    • 2018-06-07
    • 1970-01-01
    • 2019-02-05
    • 1970-01-01
    • 1970-01-01
    • 2021-04-02
    • 2018-04-08
    • 2013-08-13
    相关资源
    最近更新 更多