Javascript 如何用Jest为有承诺的代码编写单元测试
我正试图用Jest和Jasmine pit为下面的代码编写一个单元测试,我完全被它难住了。代码是一个ajax调用,它从资源中检索一些数据并将其保存在变量中Javascript 如何用Jest为有承诺的代码编写单元测试,javascript,unit-testing,jasmine,jestjs,Javascript,Unit Testing,Jasmine,Jestjs,我正试图用Jest和Jasmine pit为下面的代码编写一个单元测试,我完全被它难住了。代码是一个ajax调用,它从资源中检索一些数据并将其保存在变量中 init = function() { var deferred = Q.defer(); $.ajax({ type: 'GET', datatype: 'json', url: window.location.origin + name, success: f
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;
},
这让我今天大部分时间都很沮丧。以下是我的最终结果(测试我的ActionCreator(Flux),它使用一个API返回承诺并根据承诺发送内容)。基本上,我模拟了返回承诺的API方法,并立即解决它。您可能认为这足以激发.then(…)方法,但pit代码要求我的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});
});
});
});
下面是ActionCreator,它将API绑定到Dispatcher:
'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;
Jest网站上的这篇教程并没有直接回答这个问题,而是提供了如何进行单元测试的要点 不相关的评论(您已经有了答案):,不要使用它们:)。