你如何存根获取api请求

时间:2017-06-05 13:07:41

标签: javascript sinon fetch-api

我遇到使用fetch的存根/测试功能的问题。

使用简单的例子:

export const clickTimeseries => {
  return fetch('...url...')
    .then(response => {
      if(response.status == 200)
        return response.json()
      else
        throw 'something'
    })
    .then(json => {
      return {
        success: true,
        data: json,
      }
    })
    .catch(err => {
      return {
        success: false,
        error: err,
      }
    })
}

我的测试:

import { expect } from 'chai'
import sinon from 'sinon' 

import Promise from 'es6-promise' 
Promise.polyfill() 

import 'whatwg-fetch'

import clickTimeseries from './above'

const jsonOK = body => {  
  const mockResponse = new Response(JSON.stringify(body), {  
    status: 200,
    headers: { 
      'Content-type': 'application/json'
    }
  })

  return Promise.resolve(mockResponse) 
}

describe('APIs', () => {  
  describe('Click timeseries', () => { 
    it('builds a correct data on success', () => { 
      sinon.stub(window, 'fetch').returns(jsonOK({stuff: [1,2,3]})) 

      expect(clickTimeseries()).to.eq({ 
        success: true,
        data: {stuff: [1,2,3]}
      })
    })
  })
})

我收到错误:

expected { Object (, _state, ...) } to equal { success: true, data: {stuff: [ 1, 2, 3, 4 ] }}

看起来spendTimeseries会返回promise,而不是调用then块的结果。

您如何设置测试以使其通过?

1 个答案:

答案 0 :(得分:3)

我花了一些时间玩你的代码,直到我意识到错误,因为一切看起来都是正确的。事实上,确实如此。除了一件事:您正在测试的结果是异步传递的,但您正在同步测试它。这意味着您需要将测试更改为异步。

我假设您使用Mocha作为测试运行器,它有两种测试异步代码的方法。任何异步代码的一种标准方法,以及一种处理Promise的特殊方法。你可以使用适合你风格的任何东西。

如果您有任何异步代码,以后会传递结果,这是一般公式:

it('should test an async function', (callback) => {
    const expectedResult = 42;
    doSomethingAsync((result) => {
        try{
            expect(expectedResult).to.equal(result);
            callback();
        } catch(err) {
            callback(err);
        }
    })
});

对于承诺返回函数,这将是这样的:

it('should test a promise', (callback) => {
    const expectedResult = 42;
    doSomethingAsync().then((result) => {
        expect(expectedResult).to.equal(result);
        callback();
    }).catch(callback);
});

Mocha有一些承诺的糖,可以像这样编写最后一个函数(在函数包装器中没有回调!):

it('should test a promise', () => {
    const expectedResult = 42;
    return doSomethingAsync().then((result) => {
        expect(expectedResult).to.equal(result);
    })
});

总之:只需将测试改为:

return clickTimeseries().then( result => {
    expect(result).to.eq({ 
        success: true,
        data: {stuff: [1,2,3]}
    })
})