chai-as-promised 拒绝不会导致测试失败,但只会打印警告

imr*_*rok 2 javascript node.js promise chai

我正在用来chai-as-promised测试我的readIndex(path): string功能。

\n\n

readIndex () 返回一个 Promise,该 Promise 依次尝试打开index.json目标文件夹中指定的文件并将其解析为 JSON。

\n\n

请参阅以下摘录:

\n\n
// readIndex.js\nmodule.exports = path =>\n  new Promise((resolve, reject) => {\n    try {\n      const buffer = fs.readFileSync(path + \'/index.json\')\n      const data = JSON.parse(buffer.toString())\n      resolve(data)\n    } catch (err) {\n      if (err.code === \'ENOENT\') {\n        reject(Error(\'file not found\'))\n      } else if (err instanceof SyntaxError) {\n        reject(Error(\'format not json\'))\n      } else {\n        reject(err)\n      }\n    }\n  })\n
Run Code Online (Sandbox Code Playgroud)\n\n

通过我的案例测试的模拟,返回的承诺被拒绝,并出现错误找不到文件”。

\n\n

但实际上我正在测试一个(应该是)有效的案例,只有当承诺成功解决时才应该通过......

\n\n

至少这是我对promise.should.be.fulfilled用法的理解。

\n\n

请参阅相关测试:

\n\n
// readIndex.test.js\nchai.use(chaiAsPromised)\nchai.should()\n\ndescribe(\'SUCCESS :\', () => \n  it(\'should resolve with a (markdown) string extrapoled from target folder index file\', done => {\n    const key = \'content success\'\n    mock(_mocks[key])\n    const promise = readIndex(\'test\')\n    promise.should.be.fulfilled\n    mock.restore()\n    done()\n  }))\n
Run Code Online (Sandbox Code Playgroud)\n\n

通过这样的设置,运行测试不会使其失败;它会打印此消息:

\n\n
// readIndex.js\nmodule.exports = path =>\n  new Promise((resolve, reject) => {\n    try {\n      const buffer = fs.readFileSync(path + \'/index.json\')\n      const data = JSON.parse(buffer.toString())\n      resolve(data)\n    } catch (err) {\n      if (err.code === \'ENOENT\') {\n        reject(Error(\'file not found\'))\n      } else if (err instanceof SyntaxError) {\n        reject(Error(\'format not json\'))\n      } else {\n        reject(err)\n      }\n    }\n  })\n
Run Code Online (Sandbox Code Playgroud)\n\n

当然,预期的结果应该是测试运行失败,并在控制台中显示如下内容:

\n\n
// readIndex.test.js\nchai.use(chaiAsPromised)\nchai.should()\n\ndescribe(\'SUCCESS :\', () => \n  it(\'should resolve with a (markdown) string extrapoled from target folder index file\', done => {\n    const key = \'content success\'\n    mock(_mocks[key])\n    const promise = readIndex(\'test\')\n    promise.should.be.fulfilled\n    mock.restore()\n    done()\n  }))\n
Run Code Online (Sandbox Code Playgroud)\n\n

这种奇怪的行为甚至会导致(有趣且)语无伦次的警告。

\n\n

使用时promise.should.not.be.rejected,我得到了“预期承诺不会被拒绝,但它被拒绝了”,但测试仍然通过:

\n\n
    SUCCESS :\n          \xe2\x88\x9a should resolve with a (markdown) string extrapoled from target folder index file\n    (node:183516) UnhandledPromiseRejectionWarning: AssertionError: expected promise to be fulfilled but it was rejected with \'Error: file not found\'\n    (node:183516) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 10)\n    (node:183516) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.\n
Run Code Online (Sandbox Code Playgroud)\n\n

其实我的想法是:

\n\n
    \n
  • 一个解决方案是提高测试失败警告的级别,但我在文档中没有找到它chai-as-promised

  • \n
  • 另一个解决方案是了解哪一层正在捕获错误/拒绝,并将其降低为警告。也许是chai-as-promised默认参数?

  • \n
\n

imr*_*rok 5

chai-as-promised我刚刚在文档中发现了这个小事实:

\n\n

测试“行”(我没有更好的词)之前必须有一个 return 声明

\n\n

让我们看一下他们的第一个例子:

\n\n
return doSomethingAsync().should.eventually.equal("foo")\n
Run Code Online (Sandbox Code Playgroud)\n\n

下面的内容也很有趣:

\n\n
\n

或者如果您遇到 return 不优选的情况(例如风格考虑因素)或不可能(例如测试框架不允许返回承诺来表示异步测试完成),那么您可以使用以下解决方法(其中 did() 由测试框架提供\n):

\n
\n\n
doSomethingAsync().should.eventually.equal("foo").notify(done);\n
Run Code Online (Sandbox Code Playgroud)\n\n

它对我有用。

\n\n

我希望它能帮助人们。

\n

  • `await` 而不是 `return` 也应该可以达到目的(或者可能效果更好) (2认同)