完全使用存根测试功能

时间:2019-02-07 09:07:15

标签: javascript unit-testing testing sinon stub

过去两周来,我一直在写测试。在我的工作场所,我们使用Mocha作为测试运行程序,并使用Chai作为声明库。我还使用Sinon来创建存根,并且有一些东西经常困扰着我。我已经为几个函数编写了测试,在其中测试了函数中的每个依赖关系,最糟糕的是,我什至没有考虑要测试的函数接受的参数。让我举个例子

module.exports = {
  "someFunc": (arg1, arg2) => {
    return new Promise((resolve, reject) => {
      Promise.all(arg1).then(data => {
        let someArray = ourHelperLib.toArray(data);
        let someObj = ourHelperLib.toObject(arg2);
          if(someArray.length == 0){
            reject("error");
          }else{
            resolve({
              "array": someArray,
              "object": someObj
            });
          }
        }).catch(err => {
            reject(err);
        });
    });
  },
}
  1. 现在,当我为此功能编写测试时,我遇到了用Promise.all()引发错误的情况。
  2. 对于第二个测试,我将Promise.all()存根返回一个假正值,而将ourHelperLib.toArray()存根以引发错误并检查函数是否处理错误。
  3. 对于我的第三个测试,我对Promise.all()ourHelperLib.toArray()ourHelperLib.toObject()进行了存根处理,以返回误报,然后检查输出中是否有已解决的承诺,其值是操作的结果。

从函数定义中可以很明显地看出,传递给函数的两个参数都直接传递给我正在存根的依赖项,因此我可以完全忽略那些值,这就是我的意思

const stubOurHelperLibToThrowError = argFromCaller => {
    throw new Error("This is an error");
}

由于我不处理传递给存根函数的参数,因此我根本不会根据传递给存根函数的数据来测试该函数。我只是在测试函数someFunc()的逻辑结构。

这是一个好习惯吗?我还没有找到很多可靠的答案,而且由于我负责介绍编写当前正在工作的单元测试的指南,所以我认为这很关键。

和平!

1 个答案:

答案 0 :(得分:1)

您可以将promise传递给您的函数,而不必为您正在描述的内容添加任何内容。


  

在某些情况下,我对Promise.all()存根以引发错误

与其对存根Promise.all进行存根而不是存根,只需将具有拒绝的Promise的数组传递给函数:

someFunc([Promise.reject(new Error('fail'))], null)

...这将导致Promise.all落入catch并因错误而拒绝。


  

我将Promise.all()存根以返回一个假正值,然后将ourHelperLib.toArray()存根以引发错误并检查函数是否处理

再次,而不是对Promise.all进行存根处理,只需传递具有解析的Promise的数组:

someFunc([Promise.resolve('a value')], null)

您可以存根ourHelperLib.toArray引发错误,也可以让Promise数组解析为已知会导致ourHelperLib.toArray引发的错误。


  

对于我的第三个测试,我对Promise.all(),ourHelperLib.toArray()和ourHelperLib.toObject()进行存根以返回假阳性结果,然后检查输出中是否有已解决的承诺,其值是操作的结果。

ourHelperLib.toArrayourHelperLib.toObject进行插拔是可选的。除非它们在计算上很昂贵(例如,如果进行网络调用),那么通常都可以像平常一样调用它们。

您可以在解析的ourHelperLib.toArray数组中传递要给Promise的数据,只需将要发送的值作为第二个参数传递给ourHelperLib.toObject:< / p>

someFunc([
  Promise.resolve('value 1 for ourHelperLib.toArray'),
  Promise.resolve('value 2 for ourHelperLib.toArray')
], 'value for ourHelperLib.toObject')

...并检查结果Promise是否解析为期望值。


通常,最佳做法是坚持黑盒测试。

此函数似乎没有任何副作用,仅返回一个Promise即可根据传递的参数将其解析为结果。

除非该函数具有计算上昂贵的依赖关系,否则只要有可能,最好通过简单地传递参数并验证结果来测试此类函数。