gpt4 book ai didi

javascript - 如何使用 Jest 为带有 Promise 的代码编写单元测试

转载 作者:可可西里 更新时间:2023-11-01 02:08:04 24 4
gpt4 key购买 nike

我正在尝试使用 Jest 和 Jasmine-pit 为以下代码编写单元测试,但我完全被它难住了。该代码是一个 ajax 调用,它从资源中检索一些数据并将其保存在变量中。

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),它使用返回 promise 并根据 promise 分派(dispatch)内容的 API)。基本上我模拟了返回 promise 并立即解决它的 API 方法。您可能认为这足以触发 .then(...) 方法,但需要坑代码才能让我的 ActionCreator 实际上根据已解决的 promise 进行工作。

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});
});
});
});

这是将 API 绑定(bind)到 Dispatcher 的 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;

关于javascript - 如何使用 Jest 为带有 Promise 的代码编写单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28239452/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com