2015-01-30 3 views
12

Jest와 Jasmine-pit을 사용하여 아래 코드에 대한 단위 테스트를 작성하려고하는데 완전히 문제가 있습니다. 코드는 리소스에서 일부 데이터를 검색하여 변수에 저장하는 아약스 호출입니다.Jest로 단위 테스트를 작성하는 방법 Promise 코드

init = function() { 
    var deferred = Q.defer(); 
    $.ajax({ 
     type: 'GET', 
     datatype: 'json', 
     url: window.location.origin + name, 
     success: function (data) { 
      userId = data.userId; 
      apiKey = data.apiKey; 
      deferred.resolve(); 
     } 
    }); 
    return deferred.promise; 
}, 
+0

관련없는 코멘트 (당신은 이미 답을 가지고) : [인 연기 안티 패턴 (https://github.com/petkaantonov/bluebird/wiki/Promise-anti-patterns),하지 그것을 써 :). –

답변

9

오늘이 날을 좌절 시켰습니다. 여기에 내가 끝났습니다 (약속을 반환하고 약속에 따라 물건을 발송하는 API를 사용하는 나의 ActionCreator (Flux) 테스트). 기본적으로 약속을 반환하고 즉시 해결하는 API 메소드를 조롱합니다. .then (...) 메소드를 실행하기에 충분할 것이라고 생각 하겠지만 피트 코드는 내 ActionCreator가 실제로 해결 된 약속을 기반으로 작동하도록 요구되었습니다. 여기

jest.dontMock('../LoginActionCreators.js'); 
jest.dontMock('rsvp'); //has to be above the require statement 

var RSVP = require('rsvp'); //could be other promise library 

describe('LoginActionCreator', function() { 
    pit('login: should call the login API', function() { 
    var loginActionCreator = require('../LoginActionCreators'); 
    var Dispatcher = require('../../dispatcher/Dispatcher'); 
    var userAPI = require('../../api/User'); 
    var Constants = require('../../constants/Constants'); 

    //my api method needs to return this 
    var successResponse = { body: {"auth_token":"Ve25Mk3JzZwep6AF7EBw=="} }; 

    //mock out the API method and resolve the promise right away 
    var apiMock = jest.genMockFunction().mockImplementation(function() { 
     var promise = new RSVP.Promise(function(resolve, reject) { 
     resolve(successResponse); 
     }); 

     return promise; 
    }); 
    //my action creator will dispatch stuff based on the promise resolution, so let's mock that out too 
    var dispatcherMock = jest.genMockFunction(); 

    userAPI.login = apiMock; 
    Dispatcher.dispatch = dispatcherMock; 

    var creds = { 
     username: 'username', 
     password: 'password' 
    }; 

    //call the ActionCreator 
    loginActionCreator.login(creds.username, creds.password); 

    //the pit code seems to manage promises at a slightly higher level than I could get to on my 
    // own, the whole pit() and the below return statement seem like they shouldnt be necessary 
    // since the promise is already resolved in the mock when it is returned, but 
    // I could not get this to work without pit. 
    return (new RSVP.Promise(function(resolve) { resolve(); })).then(function() { 
     expect(apiMock).toBeCalledWith(creds); 
     expect(dispatcherMock.mock.calls.length).toBe(2); 
     expect(dispatcherMock.mock.calls[0][0]).toEqual({ actionType: Constants.api.user.LOGIN, queryParams: creds, response: Constants.request.PENDING}); 
     expect(dispatcherMock.mock.calls[1][0]).toEqual({ actionType: Constants.api.user.LOGIN, queryParams: creds, response: successResponse}); 
    }); 
    }); 
}); 

은 Dispatcher에 API를 묶는 ActionCreator입니다 : 농담의 웹 사이트에서이 튜토리얼이 직접 질문에 대답하지 않습니다

'use strict'; 

var Dispatcher = require('../dispatcher/Dispatcher'); 
var Constants = require('../constants/Constants'); 
var UserAPI = require('../api/User'); 


function dispatch(key, response, params) { 
    var payload = {actionType: key, response: response}; 
    if (params) { 
    payload.queryParams = params; 
    } 
    Dispatcher.dispatch(payload); 
} 

var LoginActionCreators = { 

    login: function(username, password) { 
    var params = { 
     username: username, 
     password: password 
    }; 

    dispatch(Constants.api.user.LOGIN, Constants.request.PENDING, params); 

    var promise = UserAPI.login(params); 

    promise.then(function(res) { 
     dispatch(Constants.api.user.LOGIN, res, params); 
    }, function(err) { 
     dispatch(Constants.api.user.LOGIN, Constants.request.ERROR, params); 
    }); 
    } 
}; 

module.exports = LoginActionCreators; 
관련 문제