6

我有以下情况:

js

import fetch from 'node-fetch'
import httpClient from './myClient/httpClient'

 export default class{
    async init(){
       const response = await fetch('some_url')
       return httpClient.init(response.payload)
    }
}

A_spec.js

import test from 'ava'
import sinon from 'sinon'
import fetch from 'node-fetch'
import httpClient from './myClient/httpClient'
import A from './src/A'

test('a async test', async (t) => {
    const instance = new A()
    const stubbedHttpInit = sinon.stub(httpClient, 'init')
    sinon.stub(fetch).returns(Promise.resolve({payload: 'data'})) //this doesn't work

    await instance.init()
    t.true(stubbedHttpInit.init.calledWith('data'))
})

我的想法是检查是否已使用获取请求中获得的有效负载调用了 httpClient 的 init 方法。

我的问题是:当我测试 A 的 init 方法时,如何模拟存根返回值的 fetch 依赖项?

4

5 回答 5

8

最后我解决了这个问题,fetch.Promise像这样存根引用:

sinon.stub(fetch, 'Promise').returns(Promise.resolve(responseObject))

对此的解释是,它node-fetch引用了本机 Promise,当您调用 时fetch(),此方法返回一个fetch.Promise. 看一下这个

于 2017-05-15T13:28:47.897 回答
3

sinon.stub(fetch)不能存根函数本身。相反,您需要node-fetch从内部存根依赖项./src/A,可能使用类似proxyquire

import proxyquire from 'proxyquire`
const A = proxyquire('./src/A', {
  'node-fetch': sinon.stub().returns(Promise.resolve({payload: 'data'}))
})
于 2017-05-15T08:50:39.113 回答
2

fetch()您可以按照手册中的说明存根

import sinon from 'sinon'
import * as fetchModule from 'node-fetch'
import { Response } from 'node-fetch'
// ...
const stub = sinon.stub(fetchModule, 'default')
stub.returns(new Promise((resolve) => resolve(new Response(undefined, { status: 401 }))))
// ...
stub.restore()

请注意,这fetch()是默认导出,node-fetch因此您需要 stub default

于 2021-10-14T09:59:44.347 回答
1

@mrtnlrsn 的答案不适用于从 NodeJS 中的 TypeScript 生成的文件,因为default它是一个生成的属性,导入这种依赖项的每个模块都有自己的,因此存根一个不会影响其他模块。

然而,NodeJS 允许访问导入的模块,所以存根是这样工作的:

const nodeFetchPath = require.resolve("node-fetch");
const nodeFetchModule = require.cache[nodeFetchPath];
assert(nodeFetchModule);
const stubNodeFetch = sinon.stub(nodeFetchModule, "exports");

确保您使用与node-fetch测试模块相同的模块,例如使用yarn dedupe. 或者构建自己的nodeFetchPath.

于 2021-11-24T17:46:42.700 回答
0

就我而言,我发现保留功能很有用,node-fetch因为我的模拟响应已经通过nock

为了实现这一点,我代理了上述答案中描述的依赖项,但在间谍中包装了一个 require 调用:

import proxyquire from 'proxyquire'
import { spy } from 'sinon'

const fetchSpy = spy(require('node-fetch'))
const moduleA = proxyquire(
  './moduleA',
 { 'node-fetch': fetchSpy }
)

...

expect(fetchSpy.args).toBe(...)
于 2018-04-12T20:11:13.440 回答