4

As a total novice with JavaScript, I'm struggling to understand how to "load" my code so I can test it using unit tests outside of the application.

In PHP, I have an autoloader (composer) so I can just reference the class I want to interact with and it is loaded automatically, or I can use require_once to include a physical file and the classes or functions in that file are available to me.

So, one of the classes (stored in a file src/lib/App/Calculator.js) ...

App.Calculator = (function () {

    var Calculator = function (onUpdateCallback) {
        this.amountChange = 0.00;
        this.amountDue = 0.00;
        this.amountTendered = 0.00;
        this.onUpdateCallback = onUpdateCallback;
    };

    Calculator.prototype = {
        clear: function () {
            this.amountTendered = 0.00;
            this.calculate();
        },

        calculate: function () {
            if (this.amountDue > 0) {
                this.amountChange = Math.max(0, this.getAmountTendered() - this.amountDue);
            } else {
                this.amountChange = -(this.getAmountTendered() + this.amountDue);
            }

            if (typeof this.onUpdateCallback === 'function') {
                this.onUpdateCallback(this);
            }
        },

        getAmountTendered: function () {
            return Number(this.amountTendered);
        },

        getChange: function () {
            return this.amountChange;
        },

        setAmountTendered: function (amountTendered) {
            this.amountTendered = parseFloat(amountTendered);
            this.calculate();
        },

        setAmountDue: function (amountDue) {
            this.amountDue = parseFloat(amountDue);
            if (this.amountDue < 0) {
                this.negative = true;
            }
            this.calculate();
        }
    };

    return Calculator;

})();

I want to be able to create a new instance of App.Calculator and test it, outside of the application. From the command line.

Coming from PHPUnit to JS and I know I'm missing a LOT of understanding, so any pointers (opinionated or otherwise) would be appreciated.

Richard A Quadling
  • 3,769
  • 30
  • 40
  • If you just open your website in a browser, you should be able to access `App.Calculator`, and do with it what you need. – Cerbrus Jan 03 '18 at 14:47
  • open your application to browser -> f12 -> sources -> find js file and place as many break points inside your class as you like and the reload page OR f12 -> var calc = App.calculator(); calc.getChange(); ...whatever else you want to test on your class; – Roumelis George Jan 03 '18 at 14:54
  • If you are looking for a JUnit testing framework I can recommend Facebook's [Jest](http://facebook.github.io/jest/). I basically comes with batteries included and is super easy to set up. – Herku Jan 03 '18 at 14:56
  • @RoumelisGeorge This question is about running unit tests. It's not about debugging code or manually testing it in the browser. – k0pernikus Jan 03 '18 at 14:56
  • I use mocha / chai in my nodejs projects. In regards to importing the code in those tests, I recommend using a module-based approach, see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import If the code is intended to run in the browser though, you might have to use a transpiler like babel or bundler as webpack. – k0pernikus Jan 03 '18 at 15:02
  • Since importing the classes seems to be the problem: Most testing frameworks run on node and use the CommonJS module format. Find out more about Node.js and modules in the [Node API docs](https://nodejs.org/docs/latest/api/modules.html). Local modules need to use relative paths starting with `./` or `../`. – Herku Jan 03 '18 at 15:24
  • Since this is specifically about running _from the command line_ this is *not* the same as the other questions. – WestCoastProjects Jun 05 '20 at 21:05

1 Answers1

3

The best would be to just test your code in a browser using the F12 debug command line.

Another option if you want to do it in the actual command line is to use Node.JS. This is basically a back end application for javascript and what you can do is just paste the code into a .js file, then use the CMD command: "node [yourfile.js]" and it will run the file. Using console.log you can log to the command line.

Liam
  • 27,717
  • 28
  • 128
  • 190
  • Copy/pasting code manually into the browser's command line in order to run unit tests is a terrible idea. It is far too much work. – Quentin Jan 03 '18 at 14:54
  • 1
    "then use the CMD command" — That won't help with the problem. It doesn't do anything to *test* the code. – Quentin Jan 03 '18 at 14:55
  • 1
    I'm trying to automate the test run. Several hundred classes. This is just one example. We use PHPUnit in our pipeline and that is testing upwards of 20,000 tests. We now want to get some testing on the JS code. None of us are experts and so we know we are going to have to learn things. The browser shouldn't be involved. – Richard A Quadling Jan 03 '18 at 14:57
  • 2
    The question is about test suites. Not about manually debugging code via a log-driven approach. Unit test != testing in the browser – k0pernikus Jan 03 '18 at 14:57
  • Not sure why the SO community is so toxic against newcomers. I don't think that this answer is generally wrong just not very well executed. To improve your answer: Try to explain better how make the code available in the browser. When would you chose this solution? The same for node.js. :) – Herku Jan 03 '18 at 14:59
  • Also the question is kind of hard to answer. OP does not seem to have any experience of running a node.js app but wants to test several hundred classes written in Javascript. You would usually approach this by asking questions in the comments but this is hard when don't have any reputation. When you then give an answer you are heavily downvoted. – Herku Jan 03 '18 at 15:03
  • OK. I do have node/npm/bower/grunt all working. What I can't work out is how to load a JS file in javascript. If I try to use require() I get "Cannot find module". – Richard A Quadling Jan 03 '18 at 15:10
  • @Herku Even as a comment, the suggested approach misses the point of the question. Even if refined and added with your proposed improvements, it would not solve the problem OP is facing. I know that SO gets flag for appearing harsh to newcomers, yet we should keep in mind that an answer should answer the question. If criticizing answers that fail to do that is toxic, then I am highly confused. – k0pernikus Jan 03 '18 at 15:15
  • @k0pernikus Isn't his question "How to test JavaScript code from the command line"? I suggested getting node.js and testing the code with `node [filename.js]` I trust OP to have experience of creating a new instance of his object in javascript and of him havng his own unit tests. I don't think SO is here to create unit tests for you? – Paul de Koning Jan 03 '18 at 15:25
  • @RichardAQuadling What you can do is actually make unit tests inside your Calculator.js. Make a new object in your code like: `const firstCalc = new App.Calculator();` or whatever the case may be, I expect you to be able to figure that out :) Then you can have your tests like this: `console.log( [test] )`. Now when you run Calculator.js with Node (using command `node Calculator.js` it should log to console whatever the tests you made – Paul de Koning Jan 03 '18 at 15:28
  • Opening line of the question ... "As a total novice with JavaScript, I'm struggling to understand how to "load" my code so I can test it using unit tests outside of the application." I can make unit tests. But I can't work out how to do the "include the code from the file name I've given you" bit. PHP has 'require' and 'include' as well as autoloading. I think I have to use a module? But don't know what to do. – Richard A Quadling Jan 03 '18 at 15:29
  • Unit tests are no way going into the code!!! And we have hundreds of classes to work on. The code is just classes, not constructed instances. I want to load the class in a unit test. Then I can instantiate an instance of the class. – Richard A Quadling Jan 03 '18 at 15:31
  • 1
    @RichardAQuadling Ah, with node you can require code yes. You do this using `require("./filename.js");` Inside the file you want to require however, you put the following at the bottom: `module.exports = ` followed by what you want to export. This can be anything. If you then require the file it will contain whatever you exported using `module.exports`. NOTE: If you use a function which is not in module.exports it will not work, unless the function is called by code that is inside module.exports. Example: https://gist.github.com/PauldeKoning/2077c08e80c38f79203825eefda7bd11 – Paul de Koning Jan 03 '18 at 15:37