您如何存根获取api请求 [英] How do you stub fetch api request

查看:67
本文介绍了您如何存根获取api请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用fetch进行存根/测试功能时遇到问题.

I am having a problem with stubbing/testing function that is using 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块的结果.

It looks like spendTimeseries returns promise, instead of the result of calling both then blocks.

您如何设置测试才能通过?

How would you have to setup your test to have it pass?

推荐答案

花了一些时间来处理您的代码,直到我意识到问题出在哪里,因为一切看起来都是正确的.实际上,确实如此.除了一件事:您要测试的结果是异步传递的,但是您正在同步地测试它.这意味着您需要将测试更改为异步.

It took some time of playing with your code until I realized what was wrong, because everything looked correct. And in fact, it was. Except for one thing: the result you are testing for is delivered asynchronously, but you are testing for it synchronously. That means you need to change your test to be async.

我假设您使用Mocha作为测试运行程序,它有两种测试异步代码的方法.一种用于任何异步代码的标准方法,以及一种处理Promises的特殊方法.您可以使用适合自己风格的任何东西.

I am assuming you are using Mocha as your test runner, and it has two ways of testing async code. One standard way for any async code, plus one special way of handling Promises. You can use whatever fits your style.

如果您有任何异步代码可以在以后发送结果,则这是通用公式:

If you have any async code where the result is delivered at a later time, this is the general formula:

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

对于一个承诺返回函数,它看起来像这样:

For a promise returning function this would look like this:

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

摩卡(Mocha)具有许诺,可以写出这样的最后一个函数(函数包装器中没有回调!):

Mocha has some sugar for promises making it possible to write the last function like this (no callback in function wrapper!):

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

这篇关于您如何存根获取api请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆