Exporting modules for testing within a route or controller function

I'm relatively new to NodeJS and the concept of unit testing.

Currently, I am using Jest, although the issue seems to persist with Mocha, Ava, or any other test framework. It appears that my problem revolves around the usage of export/import.

In one file named learning.js, I have defined some functions:

// learning.js

function sum(a, b) {
  return a + b
}

const multiply = (a, b) => a * b

module.exports = { sum: sum, multiply: multiply }

Additionally, there is another file called some.test.js:

// some.test.js

const { sum, multiply } = require('./learning')
// const { sum, multiply } = require('./another')

test('adds 1 + 2 to equal 3', () => {
  expect(sum(1, 2)).toBe(3)
})

test('multiplies 2 x 2 to equal 4', () => {
  expect(multiply(2, 2)).toBe(4)
})

At this point, everything runs smoothly, and all tests pass successfully.

However, there is a third file named another.js structured in the following way (utilizing express):

router.get('/another', async function(req, res) {

  // TESTING
  function sum(a, b) {
    return a + b
  }

  const multiply = (a, b) => a * b

  // PERFORM OTHER OPERATIONS...

  res.status(200).send('ok')
})

module.exports = { sum: sum, multiply: multiply }
// module.exports = router

When attempting to run the same tests from some.test.js (by simply modifying the require statement to point to another.js), the tests fail with the message:

TypeError multiply is not a function
.

I have experimented with moving the export statements elsewhere, as well as trying out different naming conventions using dot notation, yet I still cannot resolve the issue.

Any insights or suggestions would be greatly appreciated. Thank you!

Answer №1

If you're experiencing an issue with the scope of your functions like `sum` and `multiply`, it may be because they are defined within your route handler instead of being exported from `module.exports`.

One solution is to create a separate file, such as `helpers.js` or `services.js`, where you can define your functions:

const sum = (a, b) => a + b
const multiply = (a, b) => a * b

module.exports = { sum, multiply }

Then, in your express file, you can require these helper functions:

const helpers = require('./helpers.js')

router.get('/another', (req, res) => {
  helpers.sum(1,2)
  helpers.multiply(3,4)
  res.status(200).send('ok')
})

module.exports = router

This way, you can easily test the functions individually by requiring `helpers` in your test files.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Enhancing Application Performance Through Next.js Development

I'm currently working on an application using next.js and I am looking to implement code splitting in order to reduce the bundle size and load pages on demand. Unfortunately, I have not been able to find a way to do this without specifying routes. Fo ...

Bringing custom JavaScript functions into a Vue.js component

In my Vue.js project, I have an abundance of Javascript processing that is all local and doesn't require server-side functionality. I'm exploring the possibility of importing a file containing specific processing functions (such as mathematical a ...

Validation of OpenAPI requests on the client-side using React libraries

Is there a way to validate a request against a specific openAPI spec on the client side in a browser environment? I've spent countless hours searching and trying various openapi-tools, but all seem to be geared towards nodejs usage and not suitable f ...

Exploring the AngularJS global Date timezone offset

I want to display dates based on the users' time zones. I am hoping that Angular provides a way to globally configure the Date filter for this purpose. Doing it manually for each case doesn't seem right to me. My timestamps are already passed t ...

Can someone explain how to use JavaScript to make table data fill the entire row in a table?

After clicking the button, the layout of the table changes. I want to keep the original table layout even after the JavaScript function runs. I am still learning about JavaScript. function toggle(button) { if(document.getElementById("1").value=="Show ...

CORS - Preflight request response fails access control verification

I've been attempting to send a GET request to a server with the same domain as my local host, but I keep encountering the following error: The preflight request response fails the access control check: The requested resource does not have an ' ...

Adjusting jQuery inputmask mask according to dropdown selection: A complete guide

I am utilizing jQuery inputmask to achieve a specific effect: Currently, I have set up a simple formatting for US & Canada phone numbers like this: $("#user_phone").inputmask("mask", { "mask": "(999) 999-9999" }); However, I want to dynamically chan ...

What is the best way to prevent automatic trimming in EJS variable assignment in Node.js?

When I attempt to write a variable from the database into an EJS table, it is being displayed with default trimming by the EJS template. However, I would like to display the variable from the database without any default trimming. I consulted the EJS temp ...

Modifying JavaScript object values using the Object() constructor

My background is in Groovy, which has similar syntax to JavaScript. In Groovy, I can easily copy values from one map to another like this: def myMap1 = {}; def myMap2 = {}; myMap1["key1"] = "value1"; myMap1["key2"] = "value2"; myMap1["key3"] = "value3"; ...

Tips for configuring identical libraries under different names

As a Japanese web developer, I struggle with my English skills, so please bear with me. Currently, I am utilizing an npm library. I have forked the library and made some modifications to it. In order to incorporate these changes, I updated my package.js ...

Utilize the map function on an array object to present data in a table using React framework

My parent component passes an array object that looks like this: https://i.sstatic.net/Nqh81.png I want to organize these values into a table with the keys in one column and their corresponding values in other columns. The desired format is shown here: ht ...

Book a spot in IndexedDB storage

Currently, I am developing a diagnostics application that updates data to IndexedDB every three seconds. The data has a fixed size and anything older than a week is automatically removed, resulting in a maximum of 201600 entries. This simplifies the proces ...

Utilizing JavaScript to update the content of a React page

Recently, I came across an API using Swagger for documentation. Swagger generates a ReactJs webpage to document and test the API endpoints. However, my lack of knowledge in React architecture has led to a problem: Prior to accessing any endpoint, an authe ...

Creating a basic popup with jQuery: A step-by-step guide

Currently in the process of creating a webpage. Wondering how to create a popup window with an email label and text box when clicking on the mail div? ...

Javascript - formatting numbers with decimals

This question is not related to math or operators, but rather a formatting or masking issue. I am working on creating an order form that uses Javascript to tally and display the quantity and cost of each column in separate fields. I am trying to format th ...

Is it advisable to compress my API response in PHP?

At this stage, I find myself needing to generate extensive reports in order to gain a better understanding of the data at hand. To do so, I must retrieve one of my tables which contains around 50 parameters and 40,000 rows. While fetching the data via API ...

Insert a design layout into a text entry box

Currently developing an application with AngularJS and seeking a solution for adding a "template" to an HTML input field similar to a placeholder. Specifically, I have a date-field requiring user input in the format of dd/MM/yyyy or through a datepicker se ...

How to fix the "Cannot GET /" error in MERN Stack backend server?

After searching through numerous posts on stack overflow regarding this issue, I am still unable to find a clear solution. Therefore, I have decided to ask my question here with specific details of where I am struggling. Currently, I am working on the back ...

Using DefaultSeo does not override NextSeo in every component

I am looking to dynamically change the Head tag using next-seo. While browser validation will show NEXTSeo for individual pages, Twitter, Firebase's card validation tool, and others will default to next-seo-config.js. Does anyone have a solution? S ...

This function is designed to only work under specific conditions

Looking for assistance with a function that takes an item ID as input and changes its border when pressed. The goal is to increase the border width by 2px when there is no border, and remove the border completely when pressed again. Currently, only the f ...