When writing Mocha tests, it is not possible to use fat arrow functions because we sometimes need to use the this keyword to change the test's timeout for example.
describe('some description', function () {
before('blabla', function () {
this.timeout(10000);
return somePromise();
});
});
This results in the following eslint error:
Missing function expression name. (func-names)
I was wondering what was the guidelines for this case. Naming the functions is out of the question as it would add a lot of noise.
Would function blahblah() { really add that much noise?
I just don't really see the point for mocha tests and it goes against the DRY principle. e.g.
it('should return status 200', function shouldReturnStatus200() {
expect(self.res.status).to.equal(200);
});
Anyways, I added func-names: 0 to my tests/.eslintrc.
Another alternative, that would be less sweeping, is adding /* eslint-disable func-names */ to yourdescribe` block, which would disable it just for that scope.
Ok thanks.
I want to add that I agree with all @olalonde said about this matter. It also is hard for us to overwrite the rules since we use jest's way of organizing test files. The test files can be anywhere in ./**/__tests__/ folders, so customizing the rules is hard.
I'd recommend against using this in tests, if possible - doing that means you could use an arrow function.
As for the jest organization, that's an inherent flaw with it - perhaps you could use two separate eslintrc/eslintignore pairs, one for implementation, one for tests? Otherwise perhaps that's not the best way to organize tests.
Using arrow functions in mocha tests is discouraged according to their official documentation.
mocha is wrong. Using this in tests is discouraged, despite what their documentation says.
What is the reasoning behind discouraging the use of this in tests?
And what would be a better way to write mocha tests without using this? Closure variables?
this is shared mutable state, and should always be avoided when possible. What would you say you use this for in your mocha tests? I can better suggest an alternative if I know your use case.
The use case is standard with mocha tests: access variables setup in beforeEach in the tests.
Using this:
describe('some test', function() {
beforeEach(function() {
// Setup variables to be referenced in tests.
// Could also include the variables or the result of the actual test itself in order to avoid duplicating code in tests
this.someVariable = true;
});
it('should pass', function() {
expect(this.someVariable).to.be.true;
});
});
It seems to me the only other way to do this without using this is to use closure variables:
describe('some test', () => {
let someVariable = null;
beforeEach(() => {
// Setup variables to be referenced in tests.
// Could also include the variables or the result of the actual test itself in order to avoid duplicating code in tests
someVariable = true;
});
it('should pass', () => {
expect(someVariable).to.be.true;
});
});
@LeopoldoFu yes, for that you should use closed-over variables instead of mutating this - ie, the latter case.
Separately, never use noop matchers like .to.be.true - because .to.be.purple will pass too. You want .to.equal(true) so that if you use the wrong matcher, it will throw. The no-unused-expressions linter rule should complain about that.
Ok, as long as no one knows of any negative side effects.
Thanks for the additional tip on the matchers. Will implement it. I was ignoring the eslint error on them because I thought it just didn't know about matchers when writing tests.
Mocha does need this to access Mocha specific functionality within a test, such as setting an extended timeout for specific tests. This means arrow functions, which do not set this, cannot be used in all Mocha tests.
Naming the anonymous test function is cruft: the meaning of the function is described by the name of the test. Copying the name adds maintenance while gibberish decreases readability. Mocha nests test decriptions so a common name doesn't work.
Sorry @ljharb, testing is an animal that needs this.
@merriam (1) is a flaw in mocha; it should provide another API that doesn't depend on this. Re (2), the overarching value of ensuring all function expressions have names outweighs the slight redundancy when it's used in a mocha test context.
Nothing is an animal that needs this, unless it was poorly designed in the first place to require it.
Most helpful comment
thisis shared mutable state, and should always be avoided when possible. What would you say you usethisfor in your mocha tests? I can better suggest an alternative if I know your use case.