使用 Sinon,当 http 是 属性 时,我如何嘲笑 http.foo.get?

With Sinon, how can I mocked http.foo.get when http is a property?

我有一个我想测试的文件,其中 http-client 应该被模拟:

schema.js:

const { http } = require('@foo/http-client');
.......
const result = await http.foo('another-service').get('graphql', {
                query: `
    {
        SomeResolver(clientId: "${args.clientId}") {
            id
            start
            end
        }
    }
    `,
});

我需要模拟 result

schema.test.js:

const sinon = require('sinon');
const mockHttp = sinon.mock(require('@foo/http-client'));
.........
mockHttp.expects('foo').returns({
    get: (x,y) => {
        // mock the response here
    },
});

TypeError: Attempted to wrap undefined property foo as function 是上面的错误,这是有道理的,因为 httpdestructured.

但是,如果我将 expects 行更改为:

mockHttp.expects('http').returns

我收到错误 TypeError: Attempted to wrap object property http as function 这也有道理,因为 httpproperty.

如您所见,我是 Sinon 的新手,但我的问题是当 httpproperty 时我如何模拟 http.foo.get

据我了解,mocks 是针对对象的,而 expectations 是针对函数的——一一对应。

在您的上下文中,您似乎可以这样做:

const { http } = require('@foo/http-client');
const mockHttp = sinon.mock(require('@foo/http-client').http); // mind .http
mockHttp.expects('foo').returns({
    get: (x,y) => {
        // mock the response here
    },
});
http.foo().get();
mockHttp.verify();

如果您需要对其他 http 函数设置期望,您可以重复使用 mockHttp。如果您需要对模块中其他地方的函数有期望,则需要为它们在其中声明的对象创建另一个模拟,并且 verify() 其他模拟也是如此。 (反正我是这么理解的,有知道的请指正!)

在任何情况下,使用解构赋值都不会改变您的 http 变量 引用 模块的 http 属性 的事实。换句话说:

const { http } = require('@foo/http-client');
console.log( http === require('@foo/http-client').http ); // true