0

I try to call a lot of async functions in my mocha JS before hook but they are executed at last. Basically I am trying to execute repeated tests with different params from the constructor initialization.

I tried with only one function but it also execute at last.Tried to pass done() function to inner async function but it doesnt help either.

a.test.js and base.tests.js files :

describe('Test block', () => {
    before((done) => {
            const baseClass = new baseClass()
            baseTests.applyTests(done)
        });
    describe('test',()=>{
    ....first which should be executed;
    })
}
----------------------------------------------------------------
class baseClass {

    constructor() {
        init smth....
    }

    async applyTests(done) {
        await Promise.All(
        [
            a(),
            b(),
            c()
        ]
        done();
        )
    }
    async a() {
        return describe('TEST', () => {
            it('TEST', (done) => {
                chai.request(server)
                    .get(url)
                    .end((err, res) => {
                        asserts...
                        done();
                    });
            });
        }}

I expect to run first the async operations in the before hook and after that all other tests.

razi3lCast
  • 115
  • 2
  • 14

1 Answers1

1

Keep in mind that describe and it blocks do not execute any tests; they add tests to the test list that Mocha will execute. Putting a describe block inside a function called from a before hook like this won't ever end up executing code like chai.request(... etc. (And even if it did, it would be totally broken: a before hook is run before each test, you don't want to do asserts there because it won't be linked to any particular unit test.)

I can't give more concrete advice because I'm not sure what you were trying to accomplish, but in general, your describe and it blocks should be top-level constructs and not put inside other code like this.

EDIT: Just to make the execution path here clear: your before hook runs, which calls applyTests, which calls a(), which executes a describe block and adds your unit test TEST to the test list, then it returns. It then begins running tests, including test and TEST.

EDIT: Ah, makes sense, let me suggest two patterns that are often used in unit tests.

Pattern 1: "Test Loop"

This pattern creates many similar-looking tests, using an array of input params to produce appropriate test descriptions and test bodies.

[
    { foo: "milk", bar: "smoothie" },
    { foo: "yogurt", bar: "fridge" },
    { foo: "whatever", bar: "container" }
].forEach(test => {
    it("puts the " + test.foo + " in the " + test.bar, function () {
        assert(subject.someMethod(foo) === bar);
    });
});

Pattern 2: "Test Helper"

This pattern creates individual tests, but puts a common test body in a helper method so it can be reused.

function testSomeMethod(foo, bar) {
    assert(subject(foo) == "bar");
}

it("puts the milk in the fridge", function () {
    testSomeMethod("milk", "fridge");
});

it("puts the cereal in the pantry", function () {
    testSomeMethod("cereal", "pantry");
});

Examples above are very simple, but either the test loop or the test helper pattern can be used to encapsulate a much more complicated series of steps (set up a request, look at some response headers / bodies, etc.).

Elliot Nelson
  • 11,371
  • 3
  • 30
  • 44
  • Hi Eliot. Thanks for the information which is very useful. So I am doing things wrong - get it.The problem is I have many endpoints which are similar and I do for each of them exactly the same tests ( ended with more than 20 files with almost the same test scenario just different URL and params) and I wanted to have something like base test which will be called in every before block (and pass diff params) so I would not write many repeating tests. If there is any ideas you can share i will be more than grateful Searched in the mocha documents but I didn't find anything useful. – razi3lCast Dec 21 '18 at 15:14
  • Gotcha! I have appended a couple suggested approaches to my answer. (You don't really need a before hook for either approach, although you can also use a before hook as well, particularly to set up a common subject that all tests use, etc.) – Elliot Nelson Dec 21 '18 at 15:29
  • Thanks a lot for the answer.As far as I understand I should not put these in a before hook so I may need add them in a global hook which will be executed before all of the tests via require?If the answer is yes how can I accomplish when I specify which test to run - npm test 'a.test.js' it will require this global hook and run all the test in the array of prms when I want just a specific one?In the other pattern isn't actually doing the same thing as mine - you will require some file with methods like testSomeMethod and pass different prms in the different scenarios and again doing 'it' block? – razi3lCast Dec 21 '18 at 15:45
  • Usually, there is no need for a separate module or any of that; it's just an inline helper function, sitting inside the `describe` block, at the same level as the rest of your tests. If you have many reusable helper functions, then of course you could put them in a separate module and require them and call them as normal methods, from within each `it` test body. – Elliot Nelson Dec 21 '18 at 15:50
  • As far as running _specific_ tests -- you should assume that `npm test` will always load _all of your tests_, every single test from every test file, and run them all. You shouldn't be attempting to limit the number of tests run by managing what files are loaded. You can provide the command-line option `-g "partial string"` to run a particular unit test if you wish, but they should all be loaded. (See related question https://stackoverflow.com/questions/10832031/how-to-run-a-single-test-with-mocha) – Elliot Nelson Dec 21 '18 at 15:52
  • Thanks a lot Elliot! I will try that. Hope everything works perfect as you describe it. – razi3lCast Dec 21 '18 at 15:55