【问题标题】:How to write a unit test with Jest for code with Promise如何使用 Jest 为 Promise 代码编写单元测试
【发布时间】:2015-03-30 03:20:13
【问题描述】:

我正在尝试使用 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;
},

【问题讨论】:

标签: javascript unit-testing jasmine jestjs


【解决方案1】:

这让我今天大部分时间都很沮丧。这是我最终得到的结果(测试我的 ActionCreator (Flux),它使用一个返回承诺并根据承诺分派东西的 API)。基本上,我模拟了返回承诺并立即解决它的 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});
    });
  });
});

这是将 API 与 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; 

【讨论】:

    【解决方案2】:

    Jest 网站上的这个教程没有直接回答这个问题,但是有关于如何单元测试 Promise 的要点。

    https://facebook.github.io/jest/docs/tutorial-async.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-06-02
      • 1970-01-01
      • 2021-12-03
      • 2020-09-02
      • 2011-10-11
      • 2020-06-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多