简体   繁体   中英

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.

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.

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:

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)

Approach 1: Tests inside your GET result

Use describe() around the it() within the callback function and avoid arrow functions like the following:

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 .

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

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:

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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