Node.js unit-testing module has basic assertion assert.fail:
assert.fail(actual, expected, message, operator)
What does operator mean? I'm really new to unit-testing...
What the documentation says: The value of operator is being used to separate the values of actual and expected when providing an error message. This is described in Node.js' documentation for the assert module.
But, if you try this in the interactive shell you see that the parameter seems to be ignored:
> assert.fail(23, 42, 'Malfunction in test.', '###')
AssertionError: Malfunction in test.
at repl:1:9
at REPLServer.self.eval (repl.js:111:21)
at Interface.<anonymous> (repl.js:250:12)
at Interface.EventEmitter.emit (events.js:88:17)
at Interface._onLine (readline.js:199:10)
at Interface._line (readline.js:517:8)
at Interface._ttyWrite (readline.js:735:14)
at ReadStream.onkeypress (readline.js:98:10)
at ReadStream.EventEmitter.emit (events.js:115:20)
at emitKey (readline.js:1057:12)
It all makes sense when you take a look at the implementation of the assert module, lines 101-109:
function fail(actual, expected, message, operator, stackStartFunction) {
throw new assert.AssertionError({
message: message,
actual: actual,
expected: expected,
operator: operator,
stackStartFunction: stackStartFunction
});
}
So, a better description might be that it is not used automatically in the message, but it can be used if you catch the exception and create an appropriate message yourself. In consequence, this parameter may be useful if you are going to create your own testing framework.
You can force Node.js to use that parameter if you omit the message parameter, e.g. by passing undefined explicitly:
> assert.fail(23, 42, undefined, '###')
AssertionError: 23 ### 42
[...]
Related
I'm using eletron-json-storage like this:
settings.js:
const storage = require('electron-json-storage');
const defaultStoragePath = storage.getDefaultDataPath();
// Value: C:\Users\10467\AppData\Roaming\maplateditor\storage
...
defaultStorage() {
console.log("Check defaultStorage value");
console.log(defaultStoragePath);
// C:\Users\10467\AppData\Roaming\maplateditor\storage
storage.setDataPath(defaultStoragePath);
console.log(storage.getDataPath());
// C:\Users\10467\AppData\Roaming\maplateditor\storage
return storage;
}
...
this.defaultStorage().get(...)
And I checked every times variable defaultStoragePath was sure to set.
But electron-json-storage causes error:
(anonymous) # VM75 renderer_init.js:93
VM75 renderer_init.js:93 TypeError [ERR_INVALID_ARG_TYPE]: The "path" argument must be of type string. Received null
at validateString (VM19 validators.js:124)
at Object.resolve (VM28 path.js:139)
at mkdirP (VM113 F:\github\MaplatEditor\node_modules\mkdirp\index.js:25)
at VM91 F:\github\MaplatEditor\node_modules\electron-json-storage\lib\storage.js:527
at nextTask (VM93 F:\github\MaplatEditor\node_modules\async\dist\async.js:5327)
at next (VM93 F:\github\MaplatEditor\node_modules\async\dist\async.js:5334)
at VM93 F:\github\MaplatEditor\node_modules\async\dist\async.js:972
at VM91 F:\github\MaplatEditor\node_modules\electron-json-storage\lib\storage.js:524
at nextTask (VM93 F:\github\MaplatEditor\node_modules\async\dist\async.js:5327)
at Object.waterfall (VM93 F:\github\MaplatEditor\node_modules\async\dist\async.js:5337)
Is this a bug?
How can I avoid this?
Environments are:
node.js: 16.13.1
electron: 13.6.6
electron-json-storage: 4.5.0
===
Additional info:
This error not occurred with electron: 11.5.0
The difference of my code between electron: 11.5.0 and electron: 13.6.6 is:
On electron 11.5.0: Call settings.js code by:
const settings = require('electron').remote.require('./settings').init();
On electron 13.6.6: Call settings.js code through preload.js:
window.settingsBackend = require('./settings');
Maybe this difference causes different results..
Finally I found the reason...
I call "electron-json-storage" inside of "preload.js".
I don't know "preload.js" is worked on renderer process.
I must use electron-json-storage on main process.
I realized that under the contextIsolation environment, I need to completely rethink my architecture from the nodeIntegration era configuration.
====
I created example for using electron-json-storage under contextIsolation environment for people who will have similar question in future:
https://gist.github.com/kochizufan/a467c6b76390c6f1c41260614cb06a5c
This works well.
NOTE: Error handling or avoiding multiple registration of api are totally omitted in this example.
Any points for improvement are welcome.
I have tried researching other topics similar to this error message ( such as from here, here, here among others. ):
TypeError: Cannot read property 'createEvent' of null
In our test suit we have a lot of mocked network calls as a single mocking layer, but there is a throw new Error('unexpected URL') handler for missing calls.
Also, I have verified all of my ReactTesting findBy queries are correctly declared with async/await syntax. Sometimes the tests work, othertimes fails.
What is really curious, is the error happens ONLY in Circle CI before any tests run, it appears, based on the error message call stack:
#!/bin/bash -eo pipefail
yarn test:ci
yarn run v1.22.11
$ jest --ci --runInBand
/home/circleci/project/node_modules/react-dom/cjs/react-dom.development.js:3905
var evt = document.createEvent('Event');
^
TypeError: Cannot read property 'createEvent' of null
at Object.invokeGuardedCallbackDev (/home/circleci/project/node_modules/react-dom/cjs/react-dom.development.js:3905:26)
at invokeGuardedCallback (/home/circleci/project/node_modules/react-dom/cjs/react-dom.development.js:4056:31)
at flushPassiveEffectsImpl (/home/circleci/project/node_modules/react-dom/cjs/react-dom.development.js:23543:11)
at unstable_runWithPriority (/home/circleci/project/node_modules/react-dom/node_modules/scheduler/cjs/scheduler.development.js:468:12)
at runWithPriority$1 (/home/circleci/project/node_modules/react-dom/cjs/react-dom.development.js:11276:10)
at flushPassiveEffects (/home/circleci/project/node_modules/react-dom/cjs/react-dom.development.js:23447:14)
at Object.<anonymous>.flushWork (/home/circleci/project/node_modules/react-dom/cjs/react-dom-test-utils.development.js:992:10)
at Immediate.<anonymous> (/home/circleci/project/node_modules/react-dom/cjs/react-dom-test-utils.development.js:1003:11)
at processImmediate (internal/timers.js:464:21)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Exited with code exit status 1
CircleCI received exit code 1
I have not seen this error locally, even when running the same command as my Circle CI command.
Any ideas about this, other than unhandled
Can you try this. async() await and use expect() function and also catch the execption by new Error Object.
it("Should ...", async () => {
await myFn(async () => {
// some operations
expect(await element.length).toBe(10).toThrow(new Error("something went wrong!"))
});
});
Try adding expect(something...) to the tests, like mentioned here.
You should finish your test with some sort of an assertion.
I have a vorpal command that looks like this:
I am running version 1.9.5.
const vorpal = require('vorpal')()
vorpal
.command('temp [dev]')
.validate(function() {
return false
})
.action(function() {
...
})
vorpal.parse(process.argv)
And when i run pnt temp in my terminal I get this error thrown:
/Users/samm/Sites/pnt/node_modules/vorpal/dist/vorpal.js:169
throw new Error(err);
^
Error: null
at EventEmitter.<anonymous> (/Users/samm/Sites/pnt/node_modules/vorpal/dist/vorpal.js:169:17)
at callback (/Users/samm/Sites/pnt/node_modules/vorpal/dist/vorpal.js:830:22)
at /Users/samm/Sites/pnt/node_modules/vorpal/dist/vorpal.js:961:7
at EventEmitter._commandSetCallback (/Users/samm/Sites/pnt/node_modules/vorpal/dist/session.js:446:5)
at EventEmitter.session.completeCommand (/Users/samm/Sites/pnt/node_modules/vorpal/dist/session.js:526:12)
at onCompletion (/Users/samm/Sites/pnt/node_modules/vorpal/dist/session.js:456:10)
at EventEmitter.session.execCommandSet (/Users/samm/Sites/p nt/node_modules/vorpal/dist/session.js:471:5)
at EventEmitter.vorpal._exec (/Users/samm/Sites/pnt/node_modules/vorpal/dist/vorpal.js:960:18)
at EventEmitter.vorpal._execQueueItem (/Users/samm/Sites/pnt/node_modules/vorpal/dist/vorpal.js:751:17)
at EventEmitter.vorpal._queueHandler (/Users/samm/Sites/pnt/node_modules/vorpal/dist/vorpal.js:735:10)
I admit that this is looking ugly, and they will probably fix this in future versions, but this looks like the correct behaviour.
Returning false or a string from .validate should throw an error, as this means that you don't accept the arguments. If you return a string that string will be shown to the user (return "I don't want no scrubs.").
So from the code that you posted this is the correct behaviour.
If you like the errormessage from .validate to be different, I recommend you post an issue on vorpal's issue tracker. (Even though I can see you have already done that).
I wanted to write a changeable write() function.
var write = function(s) {
process.stdout.write(s);
}
write("Hello world!");
I thought you could just write it shorter:
var write = process.stdout.write;
write("Hello world!");
But here I will receive this error:
TypeError: Cannot read property 'defaultEncoding' of undefined
at Writable.write (_stream_writable.js:172:21)
at Socket.write (net.js:613:40)
at repl:1:2
at REPLServer.self.eval (repl.js:110:21)
at Interface.<anonymous> (repl.js:239:12)
at Interface.EventEmitter.emit (events.js:95:17)
at Interface._onLine (readline.js:202:10)
at Interface._line (readline.js:531:8)
at Interface._ttyWrite (readline.js:760:14)
at ReadStream.onkeypress (readline.js:99:10)
Why is that?
It all has to do with how javascript handles this. Inside the function process.stdout.write there is a call to defaultEncoding() using this variable.
In javascript, this is not assigned a value until an object invokes the function where this is defined and it is relative to the calling object.
So in your first example, this points to process.stdout object and it has the method defaultEncoding.
In your second example, this is undefined since the function is being called from the global namespace. When process.stdout.write tries to call defaultEncoding, it will throw the error you mentioned.
You can manually define the this value for a function using Function.prototype.call() method. Example:
var write = process.stdout.write;
write.call(process.stdout, "Hello world!");
The first argument of call is the object to be used as this inside the function.
I recommend reading this article, it explains a lot about this in javascript.
Use the .bind() method, it is designed exactly for your case.
var write = process.stdout.write.bind(process.stdout);
write("Hello world!");
This sets this variable inside the process.stdout.write method to process.stdout.
i try to use the testing tool mocha in node. Consider the following test scenario
var requirejs = require('requirejs');
requirejs.config({
//Pass the top-level main.js/index.js require
//function to requirejs so that node modules
//are loaded relative to the top-level JS file.
nodeRequire: require
});
describe('Testing controller', function () {
it('Should be pass', function (done) {
(4).should.equal(4);
done();
});
it('Should avoid name king', function (done) {
requirejs(['../server/libs/validate_name'], function (validateName) {
var err_test, accountExists_test, notAllow_test, available_test;
validateName('anu', function (err, accountExists, notAllow, available) {
accountExists.should.not.be.true;
done();
});
});
});
});
as a testing result i have got:
$ make test
./node_modules/.bin/mocha \
--reporter list
. Testing controller Should be pass: 0ms
1) Testing controller Should avoid name anu
1 passing (560 ms)
1 failing
1) Testing controller Should avoid name anu:
Uncaught TypeError: Cannot read property 'should' of null
at d:\townspeech\test\test.spec.js:23:30
at d:\townspeech\server\libs\validate_name.js:31:20
at d:\townspeech\test\test.spec.js:22:13
at Object.context.execCb (d:\townspeech\node_modules\requirejs\bin\r.js:1869:33)
at Object.Module.check (d:\townspeech\node_modules\requirejs\bin\r.js:1105:51)
at Object.Module.enable (d:\townspeech\node_modules\requirejs\bin\r.js:1376:22)
at Object.Module.init (d:\townspeech\node_modules\requirejs\bin\r.js:1013:26)
at null._onTimeout (d:\townspeech\node_modules\requirejs\bin\r.js:1646:36)
at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)
make: *** [test] Error 1
The first pass without any complication but the second, it seems like, that could not attach module shouldjs. Why?
I had the same problem. I solved it by using:
(err === null).should.be.true;
You can use should directly
should.not.exist(err);
That's a known problem with the should library: As it extends object, of course it only works when you have a concrete object. As null, by definition, means that you don't have an object, you can not call any methods on it or access any of its properties.
Hence, should is not available in this case.
Basically, you have two options of how to deal with this:
You could exchange actual and expected. This way, as long as you do not expect null, you have an object in the beginning and hence can access its should property. But, this is not nice, as it changes semantics, and does not work in all cases.
You could exchange the should library by another assertion library that does not have this problem.
Personally, I'd go with option 2, and my highly subjective personal favorite for this is node-assertthat (which has been written by me, hence it's my favorite).
Anyway, there are lots of other options, such as expect. Feel free to use any of these assertion libraries that best suits your style of writing tests.
One more option that I don't see mentioned here:
should(err === null).be.null
In you example that would would be:
should(accountExists).be.null
I always find expect works better with null and undefined as follows:
expect(err).be.null