Mocha: after() hook called even if this.skip() is called in the before() hook.

Created on 1 Dec 2017  路  3Comments  路  Source: mochajs/mocha

Prerequisites

  • [ x] Checked that your issue isn't already filed by cross referencing issues with the common mistake label
  • [x ] Checked next-gen ES issues and syntax problems by using the same environment and/or transpiler configuration without Mocha to ensure it isn't just a feature that actually isn't supported in the environment in question or a bug in your code.
  • [x ] 'Smoke tested' the code to be tested by running it outside the real test suite to get a better sense of whether the problem is in the code under test, your usage of Mocha, or Mocha itself
  • [ x] Ensured that there is no discrepancy between the locally and globally installed versions of Mocha. You can find them with:
    node node_modules/.bin/mocha --version(Local) and mocha --version(Global). We recommend avoiding the use of globally installed Mocha.

Description

As the title says. If I call this.skip() in the before hook, the after hook is still called.
Is this a correct behavior?

describe('test', function () {
   before(function() {
        this.skip();
    });
    it('it', function* () {
        // foobar
    });
    after(function() {
        // Will be called
    });
});

It can be solved by calling this.skip(); in the after hook as well. But since the DOC says:

Mocha provides the hooks before(), after(), beforeEach(), and afterEach(). These should be used to set up preconditions and clean up after your tests.

It feels like an odd behavior that skipping the test in before still results in after being called.
Not test setup was done so why should the cleanup still be executed?

Kind regards,
Edvin

P.S
I'm quite new to github so please excuse any rookie mistakes that I've made.
I hope I have provided all the necessary information in a good manner.
Thank you for any and all help.

Versions

If applicable, please specify:

  • The output of mocha --version and node node_modules/.bin/mocha --version: 3.5.0
  • The output of node --version: v6.10.3
  • The version and architecture of your operating system: Ubuntu 17.04 x86_64
  • Your shell (bash, zsh, PowerShell, cmd, etc.): bash
  • Your browser and version (if running browser tests):
  • Any other third party Mocha related modules (with versions):
  • The code transpiler being used:
question

Most helpful comment

Hi @EdvinOlofsson! That's a good question. I think the crux of it is here:

No test setup was done so why should the cleanup still be executed?

As a matter of fact, this.skip can be called anywhere in the hook, so test setup may have been done and Mocha doesn't really know whether it was or not. And even without this.skip, it's possible for setup processes to complete partially before throwing an error, which presents a similar problem for Mocha. (Hypothetically, if setup were encouraged to split up into more steps by some system wherein cleanup steps are associated with specific setup steps, neither of these would be an issue; but I'm not sure whether that can be done in Mocha's style of UI.)

All 3 comments

Hi @EdvinOlofsson! That's a good question. I think the crux of it is here:

No test setup was done so why should the cleanup still be executed?

As a matter of fact, this.skip can be called anywhere in the hook, so test setup may have been done and Mocha doesn't really know whether it was or not. And even without this.skip, it's possible for setup processes to complete partially before throwing an error, which presents a similar problem for Mocha. (Hypothetically, if setup were encouraged to split up into more steps by some system wherein cleanup steps are associated with specific setup steps, neither of these would be an issue; but I'm not sure whether that can be done in Mocha's style of UI.)

Humm I see. That makes a lot of sense. Thanks for clearing that up for me!

I have recently ran into this issue as well and initially I started to wrap the after hooks in "exception swallowers", which works, but I find it a bit ugly. So I thought I'd try @EdvinOlofsson's suggestion to also call this.skip() in after(), but that apparently no longer works:

  1) Service
       "after all" hook in "Service":
     Error: `this.skip` forbidden

Is this expected? If yes, what is the recommended way how to skip after hooks then? I can open a new issue for that, if this is out of scope here.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

robertherber picture robertherber  路  3Comments

jamietre picture jamietre  路  3Comments

CADBOT picture CADBOT  路  3Comments

daleharvey picture daleharvey  路  4Comments

wzup picture wzup  路  3Comments