Mocha: Add 'around' and 'aroundEach'

Created on 11 Mar 2014  路  3Comments  路  Source: mochajs/mocha

Right now, we can enhance our suites with before, beforeEach, after, and afterEach.

That ignores a whole class of helper function: those that temporarily modify global state. (You know they exist!)

For instance, take this CoffeeScript function:

withAnimationsDisabled = (code) ->
  x = jQuery.fx.off
  jQuery.fx.off = true
  code()
  jQuery.fx.off = x

I'd find value if Mocha would let me do this:

aroundEach(withAnimationsDisabled)

Without aroundEach or around, there's no way to use a function such as withAnimationsDisabled. You can _test_ it, but you can't use it as a helper unless you write it in every test.

I feel that around and aroundEach promote good test suite hygiene, so I think Mocha should support them.

Precedents:

I know, I know, you can bend beforeEach and afterEach to come close to what aroundEach would do. But aroundEach is better:

  • aroundEach separates concerns. Every aroundEach can be independent of every other aroundEach. That's not the case with beforeEach and afterEach, which are often intertwined.
  • aroundEach implicitly does things in the correct order. If a beforeEach initializes 1. a database connection, and 2. some global variable pulled from the database, then code in afterEach sometimes needs to be written "backwards". (2. remove global variable; 1. kill database connection.) aroundEach makes the _correct_ ordering the _obvious_ ordering.
  • aroundEach provides a friendly interface for coding test helpers (like my withAnimationsDisabled example).

Of course, async support would be amazing. It seems straightforward, right?

I'd be happy to contribute lots of feedback and maybe some code, if this feature is a welcome one. I'm using Mocha for an integration-test suite, and it needs lots of this sort of helper (e.g., "create user / drop user").

Most helpful comment

@kwarunek @travisjeffery I need to implement something like Ruby's database_cleaner, for sequelize. Can you suggest, how I should wrap each test case, in separate sequelize transaction, without aroundEach?

All 3 comments

Everything that could be done in around(Each), can be done in before/after(Each), like you noticed. Moreover if they are well-coded there is no place (IMHO) for around. I can only imagine as a pro - possibility of mangling context of tests in "elegant" manner, but it is overstatement.

mocha doesn't this need this, maybe if there's a lot of interest and you make a pr.

re: separate concerns you can split up your before/after functions.

`javascript``
function beforeEach() {
setupHouse();
setupCar();
};

function afterEach() {
teardownHouse();
teardownHouse();
}

the ordering's clear with before/each. 

@kwarunek @travisjeffery I need to implement something like Ruby's database_cleaner, for sequelize. Can you suggest, how I should wrap each test case, in separate sequelize transaction, without aroundEach?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

KylePDavis picture KylePDavis  路  71Comments

SGD1953 picture SGD1953  路  75Comments

boneskull picture boneskull  路  76Comments

domenic picture domenic  路  43Comments

quangv picture quangv  路  38Comments