在测试中表达body-parser utf-8错误

azi*_*ium 2 node.js express postman jestjs body-parser

超级难过这个.我有一些服务器代码由于某种原因在我的测试中抛出UTF-8错误但在正常运行服务器时工作正常:

码:

export default ({ projectId = PROJECT_ID, esHost = ES_HOST } = {}) => {
  let app = express();
  app.use(cors());
  app.use(bodyParser.json({ limit: '50mb' }));

  let http = Server(app);
  let io = socketIO(http);

  let server = {
    app,
    io,
    http,
    status: 'off',
    listen(
      port = PORT,
      cb = () => {
        rainbow(`?? Listening on port ${port} ??`);
      },
    ) {
      this.http.listen(port, () => {
        main({ io, app, projectId, esHost, port });
        this.status = 'on';
        cb();
      });
    },
    close(cb = () => {}) {
      if (this.http) {
        this.http.close(() => {
          this.status = 'off';
          cb();
        });
      } else {
        throw '?? cannot close server that has not been started ??';
      }
    },
  };

  return server;
};
Run Code Online (Sandbox Code Playgroud)

用法(完全一样,但在jest测试中,body-parser无法正常工作):

import createServer from '../server'

let server = createServer()
server.listen(5050);
Run Code Online (Sandbox Code Playgroud)

我正在使用邮递员,在测试之外发布回复:

{
    "projects": [
        {
            "id": "test",
            "active": true,
            "timestamp": "2018-02-25T21:33:08.006Z"
        },
        {
            "id": "TEST-PROJECT",
            "active": true,
            "timestamp": "2018-03-05T21:34:34.604Z"
        },
        {
            "id": "asd",
            "active": true,
            "timestamp": "2018-03-06T23:29:55.348Z"
        }
    ],
    "total": 3
}
Run Code Online (Sandbox Code Playgroud)

在jest测试服务器中意外的帖子响应:

错误

UnsupportedMediaTypeError: unsupported charset "UTF-8"
   at /Users/awilmer/Projects/arranger/node_modules/body-parser/lib/read.js:83:18
   at invokeCallback (/Users/awilmer/Projects/arranger/node_modules/raw-body/index.js:224:16)
   at _combinedTickCallback (internal/process/next_tick.js:131:7)
   at process._tickCallback (internal/process/next_tick.js:180:9)

Tar*_*ani 10

所以我能够重现问题,找到问题的根源和解决方法,使其工作.问题是由jest框架引起的.

在你继续阅读线程的其余部分之前,我建议你阅读我回答的另一个Jest线程.这将有助于获得有关该require方法的一些上下文内部jest

指定在任何Jest安装发生之前运行的代码

原因

问题只发生在测试而不是生产中.这是因为jestrequire方法.

当您运行测试时,它会启动一个快速服务器,该服务器调用node_modules/raw-body/index.js如下图所示

ICONV lite

正如你所看到的encodingsnull.这是因为iconv-lite模块执行了延迟加载encodings.只有getCodec在执行方法时才会加载编码.

现在,当您的测试触发了API时,服务器需要读取正文以便getCodec调用它

延迟加载

然后,这将通过jest-runtime/build/index.js自定义require方法(如果您阅读上一个链接,则会重载).

Jest execModule

execModule有一检查this._environment.global,这是空在这种情况下,因此一个null值返回,并且永远不会模块被执行

没有全球性

现在,当您查看encodings模块的导出时,它只是一个空白对象

没有出口

所以问题纯粹是一个问题jest.一个功能玩笑主要缺乏或一个错误?

相关问题

已经在下面的线程中讨论了相关问题

https://github.com/facebook/jest/issues/2605

https://github.com/RubenVerborgh/N3.js/issues/120

https://github.com/sidorares/node-mysql2/issues/489#issuecomment-313374683

https://github.com/ashtuchkin/iconv-lite/issues/118

https://github.com/Jason-Rev/vscode-spell-checker/issues/159

固定

解决问题的方法是我们在测试过程中加载模块并强制提前加载而不是延迟加载.这可以通过index.test.js在顶部添加一行来完成

import encodings from '../../node_modules/iconv-lite/encodings';
import createServer from '@arranger/server';
Run Code Online (Sandbox Code Playgroud)

更改完所有测试通过后,虽然您在测试的网址中有错误,但您得到了 Cannot POST /

工作测试

  • 绝对精彩。我曾经度过的最好的业力。 (2认同)