简体   繁体   English

Node.js:在请求回调中运行摩卡测试

[英]Node.js: Run mocha tests in a request callback

I want to run some tests whose settings need to be downloaded first via a HTTP GET. 我想运行一些需要首先通过HTTP GET下载其设置的测试。

My download is successful but my test does not run when it's inside the request callback. 我的下载成功,但是在请求回调中时测试无法运行。 I know it's not the best structure but I'd also like to know why this is not working. 我知道这不是最好的结构,但我也想知道为什么它不起作用。

describe('test', () => {
    request.get({
        url: 'https://google.com',
    }, (err, status, body) => {
        // The content is downloaded successfully.
        console.log(body);

        // This test never runs, why?
        it('should be able to run inside a request.get', () => {
        });
    });
});

I know this code works but I would still like to know why the previous example does not. 我知道这段代码有效,但是我仍然想知道为什么前面的示例不起作用。

describe('test', () => {
    it('should be able to run inside a request.get', () => {
        request.get({
            url: 'https://google.com',
        }, (err, status, body) => {
            console.log(body);
        });
    });
});

EDIT: The suggestion provided by Jankapunkt's comment works: Moving the 'it' and 'describe' together allows for a successful download and test run. 编辑:Jankapunkt的评论提供的建议有效:将“ it”和“ describe”一起移动可以成功进行下载和测试。

request.get({
    url: 'https://google.com',
}, (err, status, body) => {
    // The content is downloaded successfully.
    console.log(body);
    // The describe and it are within the same closure.
    describe('test', () => {
        // This test runs successfully.
        it('should be able to run inside a request.get', () => {
        });
    });
});

Old subject but I did like this for a Mock mongo connection: 旧的主题,但我对Mock mongo连接很喜欢:

const manager = require('./manager')
const assert = require('assert')
const MongoClient = require('./MockMongo')
let conn

describe('test execution', function() {
  it('db connection', function (done) {
    MongoClient.connect('test url')
      .then((db) => {
        conn = db
        done()
      })
  })

  it('test 1', function (done) {
    manager.methodOfManager(conn, 'param1', 'param2')
      .then(r => {
        assert.equal(r.result, 'ok')
        done()
      })
      .catch(err => {
        console.log(err.message)
        done(err)
      })
  })
})

It will print: 它将打印:

test execution 测试执行

 ✓ db connection (5ms) ✓ Test 1 (sepa) (125ms) 

2 passing (0s) 2次通过(0秒)

Approach 1: Tests inside your GET result 方法1:在GET结果中进行测试

Use describe() around the it() within the callback function and avoid arrow functions like the following: 在回调函数中的it() describe()周围使用describe() ,并避免使用箭头函数,如下所示:

it("...", () => {});

It is discouraged in mocha when you have changing contexts. 当您更改上下文时, 不建议在摩卡咖啡中使用它。

Instead use 改为使用

it("...", function(){});

and use .bind , done() or promises when required in async tests . 并在异步测试中需要时使用.binddone()或promises。

Putting this together into your code example, you may find your code to be similar to the following: 将其放到您的代码示例中,您可能会发现您的代码类似于以下内容:

request.get({
    url: 'https://google.com',
}, (err, status, body) => {
    // The content is downloaded successfully.

    describe('test', function() {
        it('should be able to run inside a request.get', function() {
            assert.isDefined(status);
            assert.isDefined(body);
            //...and so on
        });
    });
});

By the way - it is only a bad structure if for your approach is a better structure available. 顺便说一句-如果您的方法是可用的更好结构,那只是一个不好的结构。

Approach 2 - Wrap request.get in your unit 方法2-将request.get包装在单元中

This is (in my opinion) the better and more mocha-like approach, where you execute the request inside the test and use the done() callback to notify mocha, that you are done: (在我看来)这是一种更好,更类似于摩卡的方法,在这种方法中,您可以在测试内执行请求,并使用done()回调通知摩卡您已完成:

describe('test', function() {

    let request;

    beforeEach(function(){
        // request = ...
    });

    it('should be able to get a request result', function(done) {
        request.get({
            url: 'https://google.com',
        }, (err, status, body) => {

           assert.isDefined(status);
           assert.isDefined(body);
           //...and so on

           // at the end call done
           done();
    });
});

You can ensure that request is initialized each test as a new fresh instance by using the beforeEach hook. 您可以使用beforeEach挂钩确保将每个测试的请求初始化为一个新的新实例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM