can mocha tests load reuqirements once? - node.js

I think every spec files first load by mocha and mocha runs them at least describe part if "it"s wasn't selected with "only".
// Lines before first "it" will run for every spec files
// even if I don't mark them with ".only" word
var db = require("../../node/server/db"),
should = require('should')
...;
describe("main describe...", function () {
var user = {},
apiRootUrl = "http://127.0.0.1:3000";
user.nameSurname = "Cem Topkaya";
kullanici = schema.AJV.validate(schema_name, user);
describe("child describe", function () {
it(....)
it.only(....)
it(....)
}
}
I want to run only one spec file not others. Is there any way to prevent this?

If you give to Mocha the full path of your test file, it will just load that file and no other file:
$ mocha path/to/test.js

Related

Mock file in Jest and prevent getting loaded

I have a file that uses a webworker that I want to unit test. But because Jest is flaky on ESModules, it doesn't like import.meta.url.
I don't want to test this part, I need to test the functionality around it. But because it's still included in the build, js-test keeps tripping over having this included in the build.
I abstracted it into a separate JS file worker-loader.js:
const spawnWorker = () => {
return new Worker(new URL('./worker.ts', import.meta.url));
};
module.exports = { spawnSqlJsWorker};
Which is use with a require in the main source code.
I tried adding a mocks directory with an empty mock:
const spawnWorker = () => {
return null;
};
module.exports = { spawnSqlJsWorker};
And ignore this file from jest in jest.config.js:
transformIgnorePatterns: ['worker-loader.js'],
But the loader keeps wanting to include this file. Is there a way in jest to completely ignore a file and mock the complete contents of it?

Adding batches asynchronously to a Vows suite

I've got some code like this. The idea is that I'm reading fixture data from files and using the data from each file to add a batch:
// test.js
var vows = require('vows')
, async = require('async')
, suite;
exports.suite = suite = vows.describe('My tests');
function run_tests() {
set_up = [
find_tests(tests_path) // gets test data
];
async.series(set_up, function(errs, tests) {
tests = tests.pop();
tests.forEach(function(test) {
var batch = make_batch(test); // makes a batch
suite.addBatch(batch);
})
});
}
run_tests();
Obviously vows test.js doesn't find any tests because the batches are added asynchronously. I've got no idea how to make this work though. I want to use vows to be able to use reporters.

Can I load multiple files with one require statement?

maybe this question is a little silly, but is it possible to load multiple .js files with one require statement? like this:
var mylib = require('./lib/mylibfiles');
and use:
mylib.foo(); //return "hello from one"
mylib.bar(): //return "hello from two"
And in the folder mylibfiles will have two files:
One.js
exports.foo= function(){return "hello from one";}
Two.js
exports.bar= function(){return "hello from two";}
I was thinking to put a package.json in the folder that say to load all the files, but I don't know how. Other aproach that I was thinking is to have a index.js that exports everything again but I will be duplicating work.
Thanks!!
P.D: I'm working with nodejs v0.611 on a windows 7 machine
First of all using require does not duplicate anything. It loads the module and it caches it, so calling require again will get it from memory (thus you can modify module at fly without interacting with its source code - this is sometimes desirable, for example when you want to store db connection inside module).
Also package.json does not load anything and does not interact with your app at all. It is only used for npm.
Now you cannot require multiple modules at once. For example what will happen if both One.js and Two.js have defined function with the same name?? There are more problems.
But what you can do, is to write additional file, say modules.js with the following content
module.exports = {
one : require('./one.js'),
two : require('./two.js'),
/* some other modules you want */
}
and then you can simply use
var modules = require('./modules.js');
modules.one.foo();
modules.two.bar();
I have a snippet of code that requires more than one module, but it doesn't clump them together as your post suggests. However, that can be overcome with a trick that I found.
function requireMany () {
return Array.prototype.slice.call(arguments).map(function (value) {
try {
return require(value)
}
catch (event) {
return console.log(event)
}
})
}
And you use it as such
requireMany("fs", "socket.io", "path")
Which will return
[ fs {}, socketio {}, path {} ]
If a module is not found, an error will be sent to the console. It won't break the programme. The error will be shown in the array as undefined. The array will not be shorter because one of the modules failed to load.
Then you can bind those each of those array elements to a variable name, like so:
var [fs, socketio, path] = requireMany("fs", "socket.io", "path")
It essentially works like an object, but assigns the keys and their values to the global namespace. So, in your case, you could do:
var [foo, bar] = requireMany("./foo.js", "./bar.js")
foo() //return "hello from one"
bar() //return "hello from two"
And if you do want it to break the programme on error, just use this modified version, which is smaller
function requireMany () {
return Array.prototype.slice.call(arguments).map(require)
}
Yes, you may require a folder as a module, according to the node docs. Let's say you want to require() a folder called ./mypack/.
Inside ./mypack/, create a package.json file with the name of the folder and a main javascript file with the same name, inside a ./lib/ directory.
{
"name" : "mypack",
"main" : "./lib/mypack.js"
}
Now you can use require('./mypack') and node will load ./mypack/lib/mypack.js.
However if you do not include this package.json file, it may still work. Without the file, node will attempt to load ./mypack/index.js, or if that's not there, ./mypack/index.node.
My understanding is that this could be beneficial if you have split your program into many javascript files but do not want to concatenate them for deployment.
You can use destructuring assignment to map an array of exported modules from require statements in one line:
const requires = (...modules) => modules.map(module => require(module));
const [fs, path] = requires('fs', 'path');
I was doing something similar to what #freakish suggests in his answer with a project where I've a list of test scripts that are pulled into a Puppeteer + Jest testing setup. My test files follow the naming convention testname1.js - testnameN.js and I was able use a generator function to require N number of files from the particular directory with the approach below:
const fs = require('fs');
const path = require('path');
module.exports = class FilesInDirectory {
constructor(directory) {
this.fid = fs.readdirSync(path.resolve(directory));
this.requiredFiles = (this.fid.map((fileId) => {
let resolvedPath = path.resolve(directory, fileId);
return require(resolvedPath);
})).filter(file => !!file);
}
printRetrievedFiles() {
console.log(this.requiredFiles);
}
nextFileGenerator() {
const parent = this;
const fidLength = parent.requiredFiles.length;
function* iterate(index) {
while (index < fidLength) {
yield parent.requiredFiles[index++];
}
}
return iterate(0);
}
}
Then use like so:
//Use in test
const FilesInDirectory = require('./utilities/getfilesindirectory');
const StepsCollection = new FilesInDirectory('./test-steps');
const StepsGenerator = StepsCollection.nextFileGenerator();
//Assuming we're in an async function
await StepsGenerator.next().value.FUNCTION_REQUIRED_FROM_FILE(someArg);

Mocha and ZombieJS

I'm starting a nodejs project and would like to do BDD with Mocha and Zombiejs. Unfortunately I'm new to just about every buzzword in that sentence. I can get Mocha and Zombiejs running tests fine, but I can't seem to integrate the two - is it possible to use Mocha to run Zombiejs tests, and if so, how would that look?
Just looking for "hello world" to get me started, but a tutorial/example would be even better.
Thanks!
Assuming you already have installed mocha, zombie and expect.js according to instructions, this should work for you:
// Put below in a file in your *test* folder, ie: test/sampletest.js:
var expect = require('expect.js'),
Browser = require('zombie'),
browser = new Browser();
describe('Loads pages', function(){
it('Google.com', function(done){
browser.visit("http://www.google.com", function () {
expect(browser.text("title")).to.equal('Google');
done();
});
});
});
Then you should be able to run the mocha command from your root application folder:
# mocha -R spec
Loads pages
✓ Google.com (873ms)
✔ 1 tests complete (876ms)
Note: If your tests keep failing due to timeouts, it helps to increase mocha's timeout setting a bit by using the -t argument. Check out mocha's documentation for complete details.
I wrote a lengthy reply to this question explaining important gotchas about asynchronous tests, good practices ('before()', 'after()', TDD, ...), and illustrated by a real world example.
http://redotheweb.com/2013/01/15/functional-testing-for-nodejs-using-mocha-and-zombie-js.html
if you want to use cucumber-js for your acceptance tests and mocha for your "unit" tests for a page, you can use cuked-zombie (sorry for the advertising).
Install it like described in the readme on github, but place your world config in a file called world-config.js
`/* globals __dirname */
var os = require('os');
var path = require('path');
module.exports = {
cli: null,
domain: 'addorange-macbook': 'my-testing-domain.com',
debug: false
};
Then use mocha with zombie in your unit tests like this:
var chai = require('chai'), expect = chai.expect;
var cukedZombie = require('cuked-zombie');
describe('Apopintments', function() {
describe('ArrangeFormModel', function() {
before(function(done) { // execute once
var that = this;
cukedZombie.infectWorld(this, require('../world-config'));
this.world = new this.World(done);
// this inherits the whole world api to your test
_.merge(this, this.world);
});
describe("display", function() {
before(function(done) { // executed once before all tests are run in the discribe display block
var test = this;
this.browser.authenticate().basic('maxmustermann', 'Ux394Ki');
this.visitPage('/someurl', function() {
test.helper = function() {
};
done();
});
});
it("something on the /someurl page is returned", function() {
expect(this.browser.html()).not.to.be.empty;
});

How to get nodeunit to detect and run tests included in subfolders?

I have the following folder structure to my nodeunit tests for a particular project:
/tests
/tests/basic-test.js
/tests/models/
/tests/models/model1-tests.js
/tests/models/model2-tests.js
My question is - how do I get nodeunit to automatically execute ALL of the tests in the tests folder, including the sub-directories contained within?
If I execute nodeunit tests it only executes basic-test.js and skips everything in the sub-folders by default.
Use make based magic (or shell based magic).
test:
nodeunit $(shell find ./tests -name \*.js)
Here your passing the result of running find ./tests -name \*.js to nodeunit which should run all javascript tests recursively
Nodeunit allows you to pass in a list of directories from which to run tests. I used a package called diveSync which synchronously and recursively loops over files and directories. I store all the directories in an array and pass it to nodeunit:
var diveSync = require("diveSync"),
fs = require("fs"),
nodeUnit = require('nodeunit'),
directoriesToTest = ['test'];
diveSync(directoriesToTest[0], {directories:true}, function(err, file) {
if (fs.lstatSync(file).isDirectory()) {
directoriesToTest.push(file);
}
})
nodeUnit.reporters.default.run(directoriesToTest);
While this is not an automatic solution as described above, I have created a collector file like this:
allTests.js:
exports.registryTests = require("./registryTests.js");
exports.message = require("./messageTests.js")
When I run nodeunit allTests.js, it does run all the tests, and indicates the hierarchical arrangement as well:
? registryTests - [Test 1]
? registryTests - [Test 2]
? messageTests - [Test 1]
etc...
While the creation of a new unit test file will require including it in the collector, that is an easy, one-time task, and I can still run each file individually. For a very large project, this would also allow collectors that run more than one, but not all tests.
I was looking for solutions for the same question. None of the presented answers fully suited my situation where:
I didn't want to have any additional dependencies.
I already had nodeunit installed globally.
I didn't want to maintain the test file.
So the final solution for me was to combine Ian's and mbmcavoy's ideas:
// nodeunit tests.js
const path = require('path');
const fs = require('fs');
// Add folders you don't want to process here.
const ignores = [path.basename(__filename), 'node_modules', '.git'];
const testPaths = [];
// Reads a dir, finding all the tests inside it.
const readDir = (path) => {
fs.readdirSync(path).forEach((item) => {
const thisPath = `${path}/${item}`;
if (
ignores.indexOf(item) === -1 &&
fs.lstatSync(thisPath).isDirectory()
) {
if (item === 'tests') {
// Tests dir found.
fs.readdirSync(thisPath).forEach((test) => {
testPaths.push(`${thisPath}/${test}`);
});
} else {
// Sub dir found.
readDir(thisPath);
}
}
});
}
readDir('.', true);
// Feed the tests to nodeunit.
testPaths.forEach((path) => {
exports[path] = require(path);
});
Now I can run all my tests, new and old, with a mere nodeunit tests.js command.
As you can see from the code, the test files should be inside tests folders and the folders should not have any other files.

Resources