2014-09-10 2 views
0

사용자 서명을 처리하는 컨트롤러를 단위 테스트하려고합니다. 오류가 발생하고 약속을 사용하여 코드와 관련이 있다고 생각합니다. 그러나 나는이 시점에서 정말로 확신하지 못한다. 여기 컨트롤러가 있습니다.약속이 포함 된 함수의 단위 테스트가 예상대로 작동하지 않습니다.

angular.module('app').controller('SignIn', SignIn); 

function SignIn ($scope, $state, auth) { 

    $scope.credentials = {}; 

    // signin 
    $scope.signIn = function() { 
     auth.signIn($scope.credentials) 
      .then(function() { 
       $state.go('user.welcome'); 
      }, function (res) { 
       $scope.signInError = res.statusText; 
      }); 
    }; 
} 

다음은 인증 서비스입니다.

angular.module('app').factory('auth', auth); 

function auth (session, api) { 
    return { 
     signIn : function (credentials) { 
      return api.signIn(credentials) 
       .then(function (res) { 
        session.create(res.data.sessionId, res.data.userName); 
       }); 
     }, 
     signout: function() { 
      return session.destroy(); 
     }, 
     isAuthenticated: function() { 
      return !!session.userName; 
     } 
    }; 
} 

api는 $ http promises를 반환합니다.

signIn : function (credentials) { 
    return $http.post(base + '/auth/credentials', credentials); 
} 

세션은 현재 세션 정보를 저장하고 브라우저의 쿠키에 저장하는 팩토리 일뿐입니다.

여기 난 그냥 당신이 $ scope.signIn를 호출 할 때 auth.signIn 호출하는지 테스트하기 위해 노력하고있어 내 자스민 테스트

describe('SignIn', function() { 

// setup ------------------------------------------------------------------ 

    // init app module 
    beforeEach(module('app')); 

    // inject Session service 
    beforeEach(angular.mock.inject(function (_$rootScope_, _$controller_, _auth_) { 
     $rootScope    = _$rootScope_; 
     $scope     = $rootScope.$new(); 
     controller    = _$controller_("SignIn", {$scope: $scope}); 
     auth     = _auth_; 
    })); 

    // setup spies 
    beforeEach(function() { 
     spyOn(auth, 'signIn'); 
    }); 

// tests ------------------------------------------------------------------ 

    // signin in 
    it("should call auth.signIn with the user's credentials", function() { 
     $scope.signIn(); 
     expect(auth.signIn).toHaveBeenCalled(); 
    }); 

}); 

()이다. 응용 프로그램 자체는 작동하지만이 테스트를 실행하려고하면이 오류가 발생합니다.

SignIn should call auth.signIn with the user's credentials FAILED 
TypeError: 'undefined' is not an object (evaluating 'auth.signIn($scope.credentials).then') 

거기에 기대가 있지만 $ scope.signIn();을 호출하면 오류가 발생합니다. 내가 $ scope.signIn() 전에 권한을 로그하는 경우; 나는 이것을 얻는다.

LOG: Object{signIn: function() { ... }, signout: function() { ... }, isAuthenticated: function() { ... }} 

따라서 DI가 예상대로 작동한다고 가정합니다. 나는 스파이를 세우는 여러 가지 방법을 살펴 보았지만 아직 실제로 잘못 된 것이 무엇인지 알지 못했습니다. 어떤 도움을 주시면 감사하겠습니다.

+0

아무튼 ' 질문에 답할 수는 있지만, 각도의 statusText에는 몇 가지 문제가 있습니다. 아마 당신의 잘못 되풀이에 그것을 믿지 않는 것이 가장 좋습니다 ... – marneborn

답변

0

authsignIn 기능을 염탐하기 때문입니다. 스파이가되면 스파이에서 API가 더 이상 제대로 작동하지 않을 것입니다. 따라서 .and.returnValue을 사용하여 스파이로부터 약속을 보내야합니다.

그렇게 : - (그냥 할, 또는 다른 기능의 약속)

beforeEach(inject(function (_$rootScope_, _$controller_, _auth_, _$q_) { 
    $rootScope    = _$rootScope_; 
    $scope     = $rootScope.$new(); 
    controller    = _$controller_("SignIn", {$scope: $scope}); 
    auth     = _auth_; 
    fakePromise = _$q_.when(); //get a fake promise 
})); 

beforeEach(function() { 
    spyOn(auth, 'signIn').and.returnValue(fakePromise); //return fakepromise 
}); 

Plnkr

을하고 있다면 약간의 로그인 절차 이리저리 값을 반환

fakeAuthPromise = _$q_.when(somedata); 
+0

고마워요. 나는 '.and.returnValue(); .andReturn(); 재스민 버전 차이 일 수 있습니다. $ q.when()는 무엇을하고 있습니까? 그것을 전달하지 않으면 더 많은 데이터가 일반 약속을 반환합니까? – Constellates

+0

예 $ q.when()는 약속의 객체를 반환합니다. – PSL

관련 문제