I am using Mocha to run some tests on my SnailMailAddressParser project from the command-line. Unfortunately only some tests are run before Mocha exits.
The test file is very straightforward. You can see the test file here: test/test.coffee
It seems there is a race condition somewhere. When I run npm test, it does one of two things:
Runs one test; or
Runs 34 tests, starting at address_tester.
Clearly I am doing something asynchronous that needs to be caught, but I am not quite sure what yet. In any case, I do not know how to tell Mocha to wait for any asynchronous items to be reaped (i.e. some sort of Mocha.wait_all, if that is even possible - perhaps I have to add' done() calls, but I didn't think that was necessary for synchronous testing - which I thought this might be).
I will experiment of course and post any answers I glean from my testing, but I would be grateful for any insight.
The answer was that
fs.readFile filename, "utf8", -> ...
was operating asynchronously. When I had tried using
fs.readFileSync filename, "utf8", -> ...
it was not working because I was still passing a callback instead of reading the return value.
I solved the problem by changing the callback to:
data = fs.readFileSync filename, "utf8"
as no asynchronous operation was now being called.
Related
In Express best practices guide, it says you shouldn't use synchronous functions. So they advise passing a flag --trace-sync-io to raise a warning anytime a synchronous operation is made.
So I did, but when I ran my app... I got thousands of warnings! Most of them were raised by my dependencies' code and that doesn't help much. I was expecting it to show problems with my code, for example, calls to console.log(), which is (most of the times) synchronous.
Is there a more readable version of this flag, or a more effective way of detecting unwanted synchronous calls?
I'm running my test files with script
"test": "node_modules/.bin/mocha *.test.js
but in the first test I'm sending to my Node.js server while(1); and causing it to timeout, simultaneously failing that test. That's the intended behaviour but how do I make mocha run the rest of the files after that?
There is an issue in Mocha's repository for your case.
Infinite loops seem to escape timeouts #1609
TL:DR
This is not possible in mocha(because of how node works).
You can read the interesting discussion about this problem.
The reason it blocks all the code is because of how node works.
The code is executed line by line totally in syncronous way.
The async magic happens with the node event loop .
But when you run infinite loop the event loop will be blocked because only one event can run at a time, and this event will never end:)
I know it's a bad practice, but it would be helpful to know how to deal with certain cases.
In my case I'm trying to create some files, then read them. I'm wondering how can I wait for the creation to complete, before I try to read their containing directory, without using setTimeout and conditions?
A lot of NodeJS function have synchronous counterparts, you should look for those.
Have a look at the documentation for File System at https://nodejs.org/api/fs.html.
Do a page search for 'sync' and you can see that it offers many synchronous functions.
It's not just File System that offer this. The Child_process does the same, see https://nodejs.org/api/child_process.html#child_process_child_process_execsync_command_options for example.
If you can't find a native synchronous version of a function you need, the npm registry is a good place to look, a lot of times you can find a synchronous package there.
Good luck!
p.s. It's not always bad practice to write synchronous code in NodeJS, many CLI tools are synchronous for example.
You can use async await or promise to accomplish it
Example:-
async function f() {
return 1;
}
You can pass your method inside it. it will wait till your response comes
While working with the file I/O for node I found these two functions(fs.exists and fs.existsSync) to check if a file exists in the system. What are the differences between them?
exists is non blocking, and you do subsequent work with the file through a callback.
existsSync is blocking and freezes your whole app while it is working. This can be appealing to new node users because they can continue their code on the next line. However, once you become used to using callbacks, this is a far inferior way to do things.
One is working in a synchronize way (wait until finished) and another return immediately and return a promise which has a future value.
I am using jasmine-node for doing unit testing. I did below code for mocking Date.now()
spyOn(Date, 'now').andReturn(1387636363717); //always return a fixed time
Then I tried to run jasmine-node spec/ but it stopped working with no output. I could not figure out what is the reason.
I have written a tiny test. It works just fine. Using jasmin-node in version 1.11.0.
Where is your Date.now function used then?
spyOn(Date, 'now').andReturn(1387636363717);
expect(Date.now()).toEqual(1387636363717);
The problem is that there is code in node runtime (timers.js) that calls Date.now() to mark the passage of time. If you have code that sets a timer (setTimeout) and that code is executed while not using jasmine.Clock, then you may find node.js is waiting for some time to pass before executing the next real timeout. Since this code appears to be called from outside javascript land, you can not rely
on the single-threaded nature of javascript to keep you safe from this. By putting a breakpoint on a .andCallFake on the Date.now spy, I was able to see that the execution of the spec was being indefinitely suspended waiting for a millisecond to pass.
This is a problem for me because we have a very large unit test suite and there are possibilities that setTimeout is called as a side effect of some other calls and jasmine.Clock is not used universally in every spec. Since this is the side effect of an optimization (note: 'too much overhead' in the comments), I would consider this to be a bug in node.js.
If you want to stop time for your tests:
Spy on Date.now inside your spec function (it function - not beforeEach). That way your spec won't be delayed (also explains why #marco.jantke did not see this issue).
if your code under test uses timers, use jasmine.Clock.