简体   繁体   中英

How can I test my calculator using npm test?

I have a simple calculator web project: https://github.com/DANIILNEDOSTUP/js-calculator

I want to do simple tests (addition and subtraction for example) using npm + jest . I created package.json and wrote these lines:

{
  "scripts": {
    "test": "jest"
  }
}

then created script.test.js file and wrote lines:

const add = require('./script');

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

then I call a npm test command from terminal (I use Ubuntu 20.04)

Then I see a mistake:

TypeError: Cannot read property 'addEventListener' of null

and complains about 131 lines of code

clearKey.addEventLisener('click', clearEquation);

Is it realistic to do a test?
I want to make CI / CD for this application, I don't really understand JavaScript.

The main problem I can see is that your code is not even exporting anything. You have everything in 1 single file script.js and that is not a good practice, testable code will be annoying; however, is okay for now. To solve your issue, your script should export the add method.

Something like this should work.

At the end of scripts.js write something like this

module.exports = { add }

then in your test

const { add } = require('./script');

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

EDIT

This will not work in a web browser as mentioned in the comments.

However, one hack I can think of is checking if module.exports exists. So adding to scripts.js the following code should "fix it"

if (typeof module.exports !== 'undefined') {
    module.exports = { add }
}

Another solution I can think about is move all of your test code to scripts.js which is also not a good idea (it is a really bad idea actually) and it won't solve your specific issue because you are requiring dom support.

EDIT 2 As mentioned in the comments, DOMS are not supported in node.js and the fact you are calling a test script which requires a module that tries to run the whole file which fails when it gets to the DOM part, so to better fix your issue you really need to break down your code into modules.

Additionally, we can and will use webpack in our case. This would be almost impossible (at least for me) task to do without the use of webpack. Also I highly suggest you learn webpack as it is very important in what you are trying to do.

Without further ado, here is your folder structure

  • | dist (this folder is auto generated by webpack)
  • | src
    • | arithmetics.js
    • | scripts.js
    • | index.html
    • | stlye.css
  • | package.json
  • | webpack.config.js
  • | test.js

and everything else you have, obviously it can be broken down much much more and create better code but I am trying to keep it simple here and not over complicate your logic.

Disclaimer: I am not a webpack pro at all, I am a backend engineer not frontend so whatever I am referencing in webpack here can be written much better than what I am doing

arithmetics.js

const add = (a, b) => +a + +b;
const substract = (a, b) => +a - +b;
const multiply = (a, b) => a * b;
const divide = (a, b) => (b == '0' ? 'Err' : roundResult(a / b));
const roundResult = (n) => Math.round((n + Number.EPSILON) * 100) / 100; // Rounds n to 2 decimal places

module.exports = {
      add,
      subtract,
      multiply,
      divide,
      roundResult
}

scripts.js

/* Math operations */
let equation = '0';
let previousEquation = '0';
let previousOperator = '';

const {add, substract, multiply, divide, roundResult} = require('./arithmetics');

const operate = (operator, a, b = a) => {
...

package.json

...
"scripts": {
   ...
    "dev": "webpack --mode development",
    "build": "webpack --mode production"
    "test": "jest",
   ...
},
"devDependencies": {
    "html-webpack-plugin": "^4.5.0",
    "webpack": "^5.2.0",
    "webpack-cli": "^4.1.0"
 }
...

webpack.config.js

const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require('path');

module.exports = {
  entry: './src/scripts.js',
  output: {
    filename: 'scripts.js',
    path: path.resolve(__dirname, 'dist')
  },

  plugins: [
    new HtmlWebpackPlugin({
      title: "Webpack Output",
    }),
  ],
};

test.js

const { add } = require('./src/arithmetics');

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

Note: Any file I didn't include its code then it should be untouched

Note2: Make sure to run npm install or yarn to install packages!

Now run npm run build , a new folder named dist should be generated. Copy from src index.html , style.css and from dist copy scripts.js and that should be what you upload to your server (this step can be automated so that dist will include your entire code base, but again I dont know webpack that well)

to test your code you can simply run npm test

The above code works 100% fine on my local machine.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM