Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/403.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用Jasmine spyOn和工厂中定义的对象方法_Javascript_Angularjs_Jasmine_Spyon - Fatal编程技术网

Javascript 使用Jasmine spyOn和工厂中定义的对象方法

Javascript 使用Jasmine spyOn和工厂中定义的对象方法,javascript,angularjs,jasmine,spyon,Javascript,Angularjs,Jasmine,Spyon,在我的angular JS应用程序中,我有一个mainController,它接受userFactory作为参数。 userFactory由一个名为userService的对象组成,该对象又有一个userDetails对象和一些方法,包括resetUserDetails。(见下文) 在主控制器中,我有一个注销函数,它调用userFactory.userService.resetUserDetails方法。我想用jasmine测试这个注销功能,但是我得到了一些错误。我对茉莉花很陌生,所以如果我错过

在我的angular JS应用程序中,我有一个mainController,它接受userFactory作为参数。 userFactory由一个名为userService的对象组成,该对象又有一个userDetails对象和一些方法,包括resetUserDetails。(见下文)

在主控制器中,我有一个注销函数,它调用
userFactory.userService.resetUserDetails
方法。我想用jasmine测试这个注销功能,但是我得到了一些错误。我对茉莉花很陌生,所以如果我错过了一些明显的东西,我向你道歉

因此,首先在我的Jasmine套件中,我创建了一个MainControllerSpec来测试我的mainController

在这个规范中,我注入了一个名为userFactory的工厂。我试图监视我的
resetUserDetails
方法,如下所示,但出现错误:

spyOn(userFactory, 'userService.resetUserDetails');
错误:
userService.resetUserDetails()
不存在

我通过在我的userFactory中(在userService对象之外)创建一个名为test的函数来尝试这个过程,它运行良好,因此至少我知道规范中的工厂注入设置良好。
非常感谢您的帮助。谢谢

MainControllerSpec.js 主控制器中的注销功能 用户工厂
在直接注入之前,您需要模拟您的
userFactory
。 单元测试的目标是将文件作为黑盒进行测试,而不直接测试相关方法的逻辑

对于它们,您将为
userFactory
编写规范文件

在这种情况下,您可以执行以下操作:

描述(“主控制器”,函数(){
每个之前(angular.mock.module('mapModule','ngRoute','ngTouch','ngAnimate');
var范围,userFactory;
//这里是你们工厂的方法
每个模块之前(功能($PROFECT){
$provide.value('userFactory'{
myFirstObject:{
myFirstMethod:函数(){}
}
});
}));
beforeach(注入(函数($rootScope、$controller、\u userFactory){
scope=$rootScope.$new();
userFactory=\u userFactory;
$controller('mainController'{
$scope:scope
});
}));
描述('注销函数',函数(){
它('应调用userFactory.userService对象的resetUserDetails函数并重置userDetails对象',函数(){
//这里监视方法并返回您希望在此测试中返回的内容
//或者,如果您不需要管理退货,就像您看起来不需要的那样,只需使用callThrough
spyOn(userFactory.myFirstObject,'myFirstMethod')。和.callThrough();
scope.logOut();
expect(userFactory.myFirstObject.myFirstMethod).toHaveBeenCalled();
});
});

});我刚抓到它。道歉。下面的操作很好。spyOn(userFactory.userService,'resetUserDetails')。。通常,您可能希望在控制器测试中完全模拟服务,而不是逐个监视其方法。好的,谢谢你的建议。我查一下out@estus谢谢,在我的例子中,我会这样做来监视工厂(在全局范围内):beforeach(function(){module('mapModule',{userFactory:{userService:jasmine.createSpy()});});然后在套件中:descripe('注销函数',函数(){…我应该省去spyOn行吗?我试过了,但没用。谢谢你的帮助。我是jasmineuserService的新手,不应该是间谍。它是一个包含
resetUserDetails
方法的对象。你的情况与链接答案中的情况完全相同。如果函数已经是间谍,则不需要spyOn。相反,间谍返回的值应该是be设置为
和.returnValue(…)
(如果需要)。谢谢。我明天会尝试。虽然我修复了我自己的代码,正如您在上面的评论中所看到的。我需要这样说:spyOn(userFactory.userService,'resetUserDetails');而不是:spyOn(userFactory,'userService.resetUserDetails')。。(因为我的方法在userFactory中的一个名为userService的对象中)…但是我很感谢你的建议,并将尝试你的建议。谢谢抱歉没有注意到你的方法在嵌套对象中,在回答中更改了代码谢谢。我试过了,并且工作得很好。谢谢。不过我做了一件额外的事情(感谢评论中的另一个人)。我使用jasmine.createSpy()so$provide.value('userFactory',{myFirstObject:{myFirstMethod:jasmine.createSpy()}}创建了一个间谍;然后我不需要在套件中的测试中使用spyOn,而是继续使用其余的代码。无论如何,你的答案对我的问题是正确的,所以我现在就接受它。非常感谢你。这是绝对有效的。通过这种方式,你可以直接在那里做间谍,但是如果在将来的测试中,你需要间谍只是在某个测试中,在你之前需要模拟函数,您需要正常启动定义,然后
spyOn
describe("MainController", function () { 
    beforeEach(angular.mock.module('mapModule', 'ngRoute','ngTouch', 'ngAnimate'));
    var scope, userFactory; 

    beforeEach(inject(function($rootScope, $controller, _userFactory_){
        scope = $rootScope.$new();
        userFactory = _userFactory_;
        $controller('mainController', {
            $scope: scope
        }); 
    }));


   describe('The logOut function', function() {
        it('should call the resetUserDetails function of the userFactory.userService object and reset the userDetails object', function() {
            //spyOn takes in a factory and a method of that factory 
            spyOn(userFactory, 'userService.resetUserDetails');
            //spyOn(userFactory, 'test'); tried this and it works.
            scope.logOut();
            expect(userFactory.userService.resetUserDetails).toHaveBeenCalled();  
        });
    });

});
   $scope.logOut = function(){
         userFactory.userService.resetUserDetails(); 
         //userFactory.test(); //tried this with spyOn in jasmine
    }
mapApp.factory('userFactory', function(){

    var userService = {
        /*
         * Initialize a userDetails object. 
         */
        userDetails : {   
            "userID" : null,
            "facebookUserID" : "",
            "facebookName" : "",
            "facebookProfilePic" : "",
            "userPrivilegeID" : 1,
            "userToken" : "",
            "isLoggedIn" : false
        },
        resetUserDetails : function(){
            /*
             * This method resets the userDetails object.
             */
            this.userDetails = {
                "userID" : null,
                "facebookUserID" : "",
                "facebookName" : "",
                "facebookProfilePic" : "",
                "userPrivilegeID" : 1,
                "userToken" : "",
               "isLoggedIn" : false
            };
        }
    }; 
    var test = function(){
        /*
        * for testing spyOn in Jasmine
        */
    };
    //return public API so that we can access it in all controllers
    return{
      userService: userService,
      test: test
    };
});