尝试从jest单元测试连接到mongo时超时

jay*_*ayp 13 unit-testing mongoose mongodb node.js jestjs

我想用jest和mongoose编写一些单元测试来验证与mongo的数据交互.

我不想在这里模仿mongoose,因为我特别想要验证创建/修改/处理mongo文档的方式.

package.json 配置为保留节点模块未建模:

{
  "jest": {
    "unmockedModulePathPatterns": [
      "node_modules"
    ]
  }
}
Run Code Online (Sandbox Code Playgroud)

在我的实际测试中,我已经设置了一个beforeAll()钩子来处理连接到mongo:

const mongoose = require('mongoose');

describe('MyTest', () => {

  beforeAll((done) => {
    mongoose.connect('mongodb://127.0.0.1:27017/test');

    let db = mongoose.connection;

    db.on('error', (err) => {
      done.fail(err);
    });

    db.once('open', () => {
      done();
    });
  });

  it('has some property', () => {
    // should pass but actually never gets run
    expect(1).toBe(1);
  });
});
Run Code Online (Sandbox Code Playgroud)

这是输出:

/usr/local/bin/node node_modules/jest-cli/bin/jest.js --verbose
Using Jest CLI v0.10.0, jasmine2
 FAIL  src/lib/controllers/my-controller/__tests__/my-test.js (5.403s)
MyTest
  ? it has some property

MyTest › it has some property
  - Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
        at Timer.listOnTimeout (timers.js:92:15)
1 test failed, 0 tests passed (1 total in 1 test suite, run time 5.903s)

Process finished with exit code 1
Run Code Online (Sandbox Code Playgroud)

测试每次都超时,因为done()从未在beforeAll()钩子中调用- 没有错误抛出也没有任何打印到控制台.我可以在beforeAll()钩子中放置断点来验证正在运行的代码.似乎猫鼬在尝试打开与Mongo的连接时挂起,然后开玩笑测试超时.

当我在jest环境之外运行类似的代码时,它会按预期连接(立即接近).怀疑它可能导致问题,我已经尝试完全禁用了jest的自动插件功能,但行为保持不变.

我想我错过了一些非常明显的东西......任何想法可能会发生什么?

  • jest-cli v.0.10.0
  • mongoose v.4.4.11

更新:

  • 尝试用plain替换ES6箭头函数语法function(done) {}.没有不同.
  • 尝试通过传递done参数使测试异步,并在测试完成时调用它.没有不同.
  • mongoose.connect()在声明errorconnected事件处理程序之后尝试调用
  • 尝试注释掉所有与mongoose相关的代码以检查beforeAll()钩子是否正常工作 - 确实如此.

sel*_*ish 2

Jest-jasmine 与Jasmine不同
您使用的语法实际上属于 Jasmine 2.0+,而不是 Jest-jasmine。所以如果你想继续使用 jest,你必须查看 jest 文档来找到答案。
更重要的是,“beforeAll”不是标准的 jest 注入变量,请参阅jest api

我让你的代码在 Jasmine 2.3.4 上运行,它运行得很好。我开玩笑地尝试使用 Promise/pit 来完成这项工作,但失败了。

首先,安装 jasmine

npm install -g jasmine
mkdir jasmine-test  
cd jasmine-test
jasmine init
jasmine examples
touch spec/mongodbspec.js
Run Code Online (Sandbox Code Playgroud)

这是我的目录结构:

fenqideMacBook-Pro:jasmine-test fenqi$ ls -R
.:
spec/

./spec:
mongodbspec.js  support/

./spec/support:
jasmine.json
Run Code Online (Sandbox Code Playgroud)

然后,编辑spec/mongodbspec.js,我只需在代码中添加一行“ 'use strict'; ”。

'use strict';

const mongoose = require('mongoose');

describe('MyTest', () => {

  beforeAll((done) => {
    mongoose.connect('mongodb://127.0.0.1:27017/test');

    let db = mongoose.connection;

    db.on('error', (err) => {
      done.fail(err);
    });

    db.once('open', () => {
      done();
    });
  });

  it('has some property', () => {
    // should pass but actually never gets run
    expect(1).toBe(1);
  });
});
Run Code Online (Sandbox Code Playgroud)

最后,运行 'jasmine' :

fenqideMacBook-Pro:jasmine-test fenqi$ jasmine
Started
.


1 spec, 0 failures
Finished in 0.023 seconds
Run Code Online (Sandbox Code Playgroud)