I am writing my unit tests for NodeJS using Jest.
A part of my code exits using process.exit(1), so when trying to test it using Jest, the test terminates when it comes to this line with the error Command failed with exit code 1. which is the default behaviour of process.exit(1).
Can anyone please tell how to work with Jest to handle this scenario and continue with the other tests?
I think, throwing an error instead gives a more maintainable and testable code for you. Like:
if (err) {
throw new Error("Some relevant error msg")
}
If you insist on using process.exit(1), you can test for process.exitCode, which should be 1 in your case.
Related
I wonder if there is any way to prevent tests from running when we have an error.
For example, in the beforeAll() function. I have tried "return" or "throw" an error but after that, Jest runs all of my tests.
So when my code in the beforeAll() function has an error that can affect other test results, I would like to be able to prevent Jest from running all the tests.
Jest tries to run all the tests even though we already know all the tests would fail.
You can try to use bail in config:
bail: 2 // finish after 2 failed tests
or
bail: true // finish after first
https://jestjs.io/docs/cli#--bail
To fail your test use:
fail('something wrong');
I started using jest and I now need to test callbacks.
To know when a callback was called, the done() is supposed to be used accourding to the documentation: https://jestjs.io/docs/en/asynchronous.html
However the done() is not recognized beeing undefined and is consequently throwing this Error:
Test suite failed to run
TypeScript diagnostics (customize using `[jest-config].globals.ts-jest.diagnostics` option):
pathToErrorFile:line - error TS2304: Cannot find name 'done'.
63 done();
~~~~
//code to reproduce:
test('test', ()=>{
fkt(param, ()=>{
done();
});
});
I have setup jest with node and angular and in both projects this function does not exist.
So what I want to know is, where this function is even coming from and how I can troubleshoot it.
Note that everything else (test, describe, etc. ) is working fine done() as its exception.
done is not defined as a global var. You get it passed to the test function.
test('test', done => {
fkt(param, () => {
done();
});
});
Note that if you specify done parameter, jest will detect it and will fail the test on timeout, if the done function is not called after the test has finished.
If done() is never called, the test will fail (with timeout error), which is what you want to happen.
Then, you have to call done even if the test fails - otherwise you won't see the error.
If we want to see in the test log why it failed, we have to wrap expect in a try block and pass the error in the catch block to done. Otherwise, we end up with an opaque timeout error that doesn't show what value was received by expect(data).
See Jest - Testing Asynchronous Code
Is it possible to run Mocha programmatically, yet run it in a "verbose" mode and use the results programmatically?
Right now I am using it in NodeJS via mocha modules (using chai internally in the suite for the assertions).
What I want is to get more data about the failed tests than the generic errors of style: "expected true and got false".
Is there for instance a way to check which assertion failed and why, in case of multiple assertions within a test, or receive more information about a specific test, and if yes, how?
When you run Mocha programmatically, the mocha.run() method returns a Runner object. If you listen to fail events, you'll be able to learn of all test failures. Here's an example adapted from the page I linked to above:
var Mocha = require('mocha');
var fs = require('fs');
var path = require('path');
var mocha = new Mocha();
var testDir = '.'
fs.readdirSync(testDir).filter(function(file){
// This gets all files that end with the string test.js (so
// footest.js, bar_test.js, baz.test.js, etc.
return file.substr(-7) === 'test.js';
}).forEach(function(file){
mocha.addFile(path.join(testDir, file));
});
var runner = mocha.run(function(failures){
process.on('exit', function () {
process.exit(failures);
});
});
// This is how we get results.
runner.on('fail', function(test, err){
console.log(err);
});
Is there for instance a way to check which assertion failed and why, in case of multiple assertions within a test, or receive more information about a specific test, and if yes, how?
Mocha does not provide any facility to relate the exception you get through err in the fail handler to a specific assertion. This is due to the fact that Mocha is designed to be used with whatever assertion library you want. It only detects that an assertion has failed when it catches the exception raised by the failing assertion. It does not know anything about the assertions that were successful or the assertions that were not executed because the test ended early on the failing assertion. You may be able to reverse engineer something from the stack trace but Mocha won't help you towards this goal.
I do have some problems with me very special grunt-karma-requirejs-jasmine setup. Basically I have everything up and running and as long as test are defined properly in the spec-files everything ist just working perfect, resulting in an junit-XML-file showing me test success and test failures.
Now the problem:
If there is a problem with the scripts the tests run on (e.g. variables undefined, modules not available --> everything that causes a normal browser to throw an error), my Karma stops with throwing an error, which is the default behaviour. But what I really want Karma to do is, not to stop, but log it's errors to my junit-XML-file => so I have three types of states (success, failure, error) in my XML and not on my console.
How can I:
- get Karma to custom handle errors?
- get Karma to tell karma-junit-reporter what to log?
Any help is appreciated! Thanks a lot guys!
How do I force a Mochajs test to end completely without continuing on to the next tests. A scenario could be prevent any further tests if the environment was accidentally set to production and I need to prevent the tests from continuing.
I've tried throwing Errors but those don't stop the entire test because it's running asynchronously.
The kind of "test" you are talking about --- namely checking whether the environment is properly set for the test suite to run --- should be done in a before hook. (Or perhaps in a beforeEach hook but before seems more appropriate to do what you are describing.)
However, it would be better to use this before hook to set an isolated environment to run your test suite with. It would take the form:
describe("suite", function () {
before(function () {
// Set the environment for testing here.
// e.g. Connect to a test database, etc.
});
it("blah", ...
});
If there is some overriding reason that makes it so that you cannot create a test environment with a hook and you must perform a check instead you could do it like this:
describe("suite", function () {
before(function () {
if (production_environment)
throw new Error("production environment! Aborting!");
});
it("blah", ...
});
A failure in the before hook will prevent the execution of any callbacks given to it. At most, Mocha will perform the after hook (if you specify one) to perform cleanup after the failure.
Note that whether the before hook is asynchronous or not does not matter. (Nor does it matter whether your tests are asynchronous.) If you write it correctly (and call done when you are done, if it is asynchronous), Mocha will detect that an error occurred in the hook and won't execute tests.
And the fact that Mocha continues testing after you have a failure in a test (in a callback to it) is not dependent on whether the tests are asynchronous. Mocha does not interpret a failure of a test as a reason to stop the whole suite. It will continue trying to execute tests even if an earlier test has failed. (As I said above, a failure in a hook is a different matter.)
I generally agree with Glen, but since you have a decent use case, you should be able to trigger node to exit with the process.exit() command. See http://nodejs.org/api/process.html#process_process_exit_code. You can use it like so:
process.exit(1);
As of the mocha documentation, you can add --exit flag when you are executing the tests.
It will stop the execution whenever all the tests have been executed successfully or not.
ex:
mocha **/*.spec.js --exit