Search code examples
javascriptnode.jsmocha.jssupertest

Is there any way to call a Mocha function including it() and run whatever is inside `it`?


I'm trying to call a Mocha function as simple as bellow

this.logSomething = function() {
    console.log('======== outside it ========')
    it('something inside it', function logSomething(done){
        console.log('+++++++ something inside it ++++++++') 
        done()  
    })
}

from another js file. After using mocha.run(logSomething())

======== outside it ========

appears but

+++++++ something inside it ++++++++

is missing.

I have tried using 'describe' but the result is the same. Any solutions instead of bypasses?

FYI, I know it can be run by importing it as a Mocha test and using Mocha CLI, however I want to use this method to rerun the failed functions from my test suite, therefore it could be zero or many functions with different names and it's not the simple as importing certain number of Mocha tests.

Also, I have tried Mocha's existing retry and since it doesn't match our tests, I'm not using it.


Solution

  • A simple example

    Exporting your logSomething function, importing it into another file and executing it does give me the behavior you expect:

    lib.js

    module.exports.logSomething = function() {
        console.log('======== outside it ========')
        it('something inside it', function logSomething(done){
            console.log('+++++++ something inside it ++++++++')
            done()
        })
    }
    

    test.js

    const {logSomething} = require('./lib');
    logSomething();
    logSomething();
    

    Output

    $ mocha test.js
    ======== outside it ========
    ======== outside it ========
    
    
    +++++++ something inside it ++++++++
      ✓ something inside it
    +++++++ something inside it ++++++++
      ✓ something inside it
    
      2 passing (4ms)
    

    An example with multiple files and classes

    So here's a more sophisticated example: There's one test.js, which imports two classes from two separate files. Each class has two methods that, in turn, run mocha test cases using it().

    test.js

    const {TestSet1} = require('./lib1');
    const {TestSet2} = require('./lib2');
    
    new TestSet1().runTest1();
    new TestSet1().runTest2();
    new TestSet2().runTest1();
    new TestSet2().runTest2();
    

    lib1.js

    class TestSet1 {
    
        runTest1() {
            it('should run TestSet1.Test1.It1', () => {
                console.log('This is output from TestSet1.Test1.It1');
            });
            it('should run TestSet1.Test1.It2', () => {
                console.log('This is output from TestSet1.Test1.It2');
            });
        }
    
        runTest2() {
            it('should run TestSet1.Test2.It1', () => {
                console.log('This is output from TestSet1.Test2.It1');
            });
            it('should run TestSet1.Test2.It2', () => {
                console.log('This is output from TestSet1.Test2.It2');
            });
        }
    
    }
    
    module.exports = {TestSet1};
    

    lib2.js

    class TestSet2 {
    
        runTest1() {
            it('should run TestSet2.Test1.It1', () => {
                console.log('This is output from TestSet2.Test1.It1');
            });
            it('should run TestSet2.Test1.It2', () => {
                console.log('This is output from TestSet2.Test1.It2');
            });
        }
    
        runTest2() {
            it('should run TestSet2.Test2.It1', () => {
                console.log('This is output from TestSet2.Test2.It1');
            });
            it('should run TestSet2.Test2.It2', () => {
                console.log('This is output from TestSet2.Test2.It2');
            });
        }
    
    }
    
    module.exports = {TestSet2};
    

    Output

    $ mocha test.js
    
    
    This is output from TestSet1.Test1.It1
      ✓ should run TestSet1.Test1.It1
    This is output from TestSet1.Test1.It2
      ✓ should run TestSet1.Test1.It2
    This is output from TestSet1.Test2.It1
      ✓ should run TestSet1.Test2.It1
    This is output from TestSet1.Test2.It2
      ✓ should run TestSet1.Test2.It2
    This is output from TestSet2.Test1.It1
      ✓ should run TestSet2.Test1.It1
    This is output from TestSet2.Test1.It2
      ✓ should run TestSet2.Test1.It2
    This is output from TestSet2.Test2.It1
      ✓ should run TestSet2.Test2.It1
    This is output from TestSet2.Test2.It2
      ✓ should run TestSet2.Test2.It2
    
      8 passing (9ms)