【问题标题】:Sinon - How to make a function thats called indirectly return somethingSinon - 如何使调用的函数间接返回某些内容
【发布时间】:2019-05-30 04:25:47
【问题描述】:

我一直在努力研究如何模拟一个函数,以便我可以从该函数返回一个假值。

我有一个可以进行 api 调用的简单脚本,但是这个 api 调用有两个参数。一个参数是通过父函数的参数提供的,另一个是通过调用另一个函数来提供的。这个函数的返回值是我需要模拟的。

完整的代码非常复杂,这就是为什么我做了一个小样本来说明我的意思。首先我有函数makeTheCall。在该函数中,我调用了一个名为 setParameters 的函数。

const setParams = require('setParams.js');

module.exports.makeTheCall = (event) => {
  const params = setParams('GET', '/todos/1');
  const postData = {
    name: event.name,
    location: event.location
  }

  console.log(params); //dynamic params 'method' and 'callpath' are both undefined here (should be 'GET' and '/todos/1')

  return doARequest(params, postData).then((result) => {
    return result;
  }).catch((error) => {
    return error;
  })
}

setParams 函数并不难。它只是返回一个包含一些静态值和一些动态值的对象。

module.exports.setParams = (method, callPath) => {
  return {
    host: 'jsonplaceholder.typicode.com',
    port: 433,
    method: method,
    path: callPath
  }
}

现在,有趣的部分开始发挥作用了。编写简单测试时,调用无法通过。这当然是因为它无法解析动态值methodcallPath

const makeTheCall = require('makeTheCall.js');

it('runs a happy flow scenario', () => {
  const event = {
    name: 'John Doe',
    location: 'Somewhere'
  }

  return makeTheCall(event)
    .then(response => {
      //Do some usefull testing here
    });
});

我的问题是如何模拟 setParams 方法的返回值,使其返回如下内容:

{
  host: 'jsonplaceholder.typicode.com',
  port: 433,
  method: 'GET',
  path: '/todos/1'
}

这样我可以在我的测试中调用我的 API 调用而不会导致错误。我一直在研究使用 sinon 进行模拟,尤其是 sinon 存根,例如:

const params = setParams('GET', '/todos/1');
sinon.stub(params).returns({
  host: 'jsonplaceholder.typicode.com',
  port: 433,
  method: 'GET',
  path: '/todos/1'
});

但是我认为我忽略了一些东西,因为这不起作用。文档很好,但经过几个小时的挣扎和尝试,我开始感到有点失落。

谁知道/可以为我指出如何模拟 setParams 函数的返回值的正确方向?一个例子将不胜感激。

【问题讨论】:

  • 你不需要模拟setParams。你想测试什么?从您描述的示例中,您需要模拟 doARequest 方法,该方法将根据您的模拟条件返回一个承诺,并检查是否使用 paramspostData 调用了 doARequest 并检查它是否返回模拟响应或基于您的模拟条件的错误(无论是在doARequest 的存根方法中拒绝还是解决承诺)

标签: javascript node.js unit-testing mocking sinon


【解决方案1】:

你打电话给sinon.stub 不太对。 stub() 需要一个对象和一个作为该对象属性的函数。如果您使用以下方式导入:

 const setParams = require('setParams.js');

然后setParams 将是modules.export 对象,setParams 将是一个属性,因此您可以使用以下内容存根它:

let fakeParam = {
    host: 'jsonplaceholder.typicode.com',
    port: 433,
    method: 'GET',
    path: '/todos/1'
}

let paramStub = sinon.stub(params, 'setParams').returns(fakeParam)

在更广泛的情况下,您要测试的内容并不十分清楚。通过单元测试,您通常会尝试将所有内容简化为您想要断言的一件小事。因此,在这种情况下,您可能想要断言,当您调用 makeTheCall 时,doARequest 是使用从 setParams 返回的参数调用的。在这种情况下,您还可以存根doARequest。然后你可以用sinon.calledWith(doARequestStubb, fakeParam) 断言。您可以让 doARequestStubb 解析并承诺代码不会中断。

【讨论】:

  • 我明白了。我让它工作了,但我不知道如何在 promise 的 then/catch 子句中使用假返回值。我为此here 开了一个单独的主题。你能帮我更好地理解这部分吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-14
  • 1970-01-01
  • 2015-07-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多