【问题标题】:How does one stub promise with sinon?一个stub如何与sinon约定?
【发布时间】:2013-12-31 13:21:41
【问题描述】:

我有一个具有以下功能的数据服务

function getInsureds(searchCriteria) {

    var deferred = $q.defer();

    insuredsSearch.get(searchCriteria,
        function (insureds) {
            deferred.resolve(insureds);
        },
        function (response) {
            deferred.reject(response);
        });

    return deferred.promise;
}

我想测试以下功能:

function search ()
{
  dataService
      .getInsureds(vm.searchCriteria)
      .then(function (response) {
           vm.searchCompleted = true;

            if (response.insureds.length > 100) {
              vm.searchResults = response.insureds.slice(0, 99);
            } else {
                vm.searchResults = response.insureds;
           }
       });
}

我将如何存根承诺,以便在我调用 getInsureds 时它会解决承诺并立即返回结果。我是这样开始的(茉莉花测试),但我被卡住了,因为我不知道如何解决承诺并传递所需的参数。

it("search returns over 100 results searchResults should contain only 100 records ", function () {

    var results103 = new Array();

    for (var i = 0; i < 103; i++) {
        results103.push(i);
    }

    var fakeSearchForm = { $valid: true };
    var isSearchValidStub = sinon.stub(sut, "isSearchCriteriaValid").returns(true);

    var deferred = $q.defer();
    var promise = deferred.promise;
    var dsStub = sinon.stub(inSearchDataSvc, "getInsureds").returns(promise);

    var resolveStub = sinon.stub(deferred, "resolve");

    //how do i call resolve  and pass in results103

    sut.performSearch(fakeSearchForm);

    sinon.assert.calledOnce(isSearchValidStub);
    sinon.assert.calledOnce(dsStub);

    sinon.assert.called(resolveStub);

    expect(sut.searchResults.length).toBe(100);

});

【问题讨论】:

    标签: javascript jasmine sinon


    【解决方案1】:

    目前sinon v2.3.1版本,可以使用stub.resolves(value)stub.rejects(value)函数

    例如,您可以使用以下代码存根 myClass.myFunction

    sinon.stub(myClass, 'myFunction').resolves('the value you want to return');
    

    sinon.stub(myClass, 'myFunction').rejects('the error information you want to return');
    

    【讨论】:

    • 这很优雅!谢谢!
    • 您好,如何获取返回值?
    【解决方案2】:

    您只需在调用搜索功能之前解决承诺。这样,您的存根将返回已解决的承诺,并且将立即调用 then。所以不是

    var resolveStub = sinon.stub(deferred, "resolve");
    

    您将使用您的虚假响应数据解决延迟问题

    deferred.resolve({insureds: results103})
    

    【讨论】:

    • 这不符合我们现在使用的承诺。 Promises/A+ say "在执行上下文堆栈仅包含平台代码之前,不得调用 onFulfilled 或 onRejected"。
    • 其实我是这样做的:var resolveStub = sinon.stub(deferred, "resolve").returns({then:function(){}});
    【解决方案3】:

    你也可以这样做:

    import sinon from 'sinon';
    
    const sandbox = sinon.sandbox.create();
    
    const promiseResolved = () => sandbox.stub().returns(Promise.resolve('resolved'));
    const promiseRejected = () => sandbox.stub().returns(Promise.reject('rejected'));
    
    const x = (promise) => {
      return promise()
        .then((result) => console.log('result', result))
        .catch((error) => console.log('error', error))
    }
    
    x(promiseResolved); // resolved
    x(promiseRejected); // rejected
    

    【讨论】:

      【解决方案4】:

      我遇到了类似的情况,接受的答案和 cmets 不起作用,但与 this question 一起,他们通过以下方式帮助我解决了这个问题。我希望它对某人有帮助。

      var Promise = require('bluebird');
      
      var deferred = Promise.defer();
      stub = sinon.stub(deferred, 'resolve').returns(deferred.promise);
      
      deferred.resolve({data: data});
      // or
      deferred.reject(new Error('fake error'));
      

      【讨论】:

      • 这拯救了我的一天 :)
      【解决方案5】:

      我发现了另一种选择。比其他方法更轻松。

      你可以使用这个 npm 包:sinon-stub-promise

      它抽象了很多细节,因此您不必再次发明轮子。在长时间努力模拟承诺后帮助我编写测试。

      希望对你有帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-08-21
        • 2017-03-23
        • 2019-09-30
        • 2019-01-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-22
        相关资源
        最近更新 更多