Zorayr
Zorayr

Reputation: 24922

Is there a way to check that all function references are defined in JavaScript/Node Application?

I recently extracted out a function called sendTextMessage without modifying it into its own module so that I can re-use it in a different location. I wanted to find out if the previous location correctly was referencing the function inside the module, but couldn't find an easy way other than mocking out some of the system functions and writing unit tests.

In a compiled language, the question of "is this function correctly defined" would be quickly answered, but in JavaScript/Node, I am assuming you need to either:

  1. Run the code — Too much work; I need to setup a perfect condition for this specific path to be invoked.
  2. Write unit tests — Yes, but I don't have them right now; is there an easier way to accomplish my goal?
  3. Wait for metrics — If I broke something, I would see it in metrics, but this means, I am breaking in production
  4. ESLint? — Can I check for this condition via eslint?
  5. Anything else?

In the example code below, I just recently extracted out sendTextMessage from reminders.js to twilio.js and want to make sure that the function is correctly defined in reminders.js.

Defining Module (twilio.js):

const accountSid = '...';
const authToken = '...';
const twilio = require('twilio')(accountSid, authToken, {
  // US West Coast
  edge: 'umatilla',
});

async function sendTextMessage(message, recipientNumber) {
  return twilio.messages.create({
    from: '+...',
    body: message,
    to: recipientNumber,
  });
}

module.exports = {
  twilio,
  sendTextMessage, // Recently exported function!
};

Consuming Module (reminders.js):

const {
  sendTextMessage,
} = require('./deps/twilio');

...
// Question: was sendTextMessage correctly extracted out to twilio.js and does my code actually reference it here correctly? 
await sendTextMessage(reminderMessage, participantPhoneNumber);
... 

Upvotes: 0

Views: 458

Answers (1)

Matthias
Matthias

Reputation: 15415

First off, a quick plug for typescript; you mentioned "compiled languages don't suffer from this issue", whereas javascript does. But if the code was a typescript project, it would be checkable in the way you want. Keep that in mind for the next project. Or maybe you can apply typescript checking to the current project?

There are a few answers here.

One — write the unit test. If you can't, well, that's a bad sign for the codebase. Still, write the test for your own sake. You gotta learn how to mock, and in turn you'll learn how to write code that is more easily tested.

Two — get comfortable with javascript syntax. At some point, you need to be able to rule out the possibility of these kinds of errors. Unless your codebase is overriding require, the behavior is pretty predictable.

I don't think eslint can statically analyze modules, especially when you're using require. Someone smarter than me can probably explain why; I can't.

Three, and most importantly — is there no middle ground between your code and prod? No local development or staging environment? So, there is no way run the app without pushing to prod? In that case, go ahead and risk breaking prod then; somebody higher up is making bad decisions and needs to learn.

Upvotes: 1

Related Questions