0

I try to use QUnit for testing my javascript-code. I have simple functions:

function Multiply(a, b) {
    return a * b;

}

function CalculateBodyMassIndex(weight, height) {
    return Math.round(weight / Multiply(height, height));

}

function SummAll(array) {
    var summ = 0;
    $.each(array, function (i, el) {
       summ = summ + el;
    });
    return summ;

}

I have two questions: 1) How can I verify that in function CalculateBodyMassIndex will be called Multiply function?

2) How can I verify that in function SummAll will be called $.each from jQuery library?

With thanks to waiting for an answers.

3 Answers 3

2

This is an excellent post on how to use sinon.js with QUnit for mocks http://cjohansen.no/en/javascript/using_sinon_js_with_qunit.

The spies and stubs in sinon allow you to verify calls on existing objects very easily.

EDIT The sinon.js documentation here http://sinonjs.org/docs/#spies shows how to use Spies. Browse the full API doc for examples of stubs, mocks, etc.

Sign up to request clarification or add additional context in comments.

1 Comment

Hi. Thanks for the answer and link. I have second question. How should I write a test, if I want to make sure that function will be called with the specific parameters? Unfortunately I couldn't find example in article.
0

Just paste following html and open it from your browser.

<html>
  <head>
    <title>test</title>
    <link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.11.0.css">
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
    <script src="http://code.jquery.com/qunit/qunit-1.11.0.js"></script>
    <script src="http://sinonjs.org/releases/sinon-1.6.0.js"></script>
    <script src="http://sinonjs.org/releases/sinon-qunit-1.0.0.js"></script>
    <script type="text/javascript">
      function Multiply(a, b) {
        return a * b;
      }

      function CalculateBodyMassIndex(weight, height) {
        return Math.round(weight / Multiply(height, height));
      }

      function SummAll(array) {
        var summ = 0;
        $.each(array, function (i, el) {
          summ = summ + el;
        });
        return summ;
      }
    </script>
  </head>
  <body>
    <div id="qunit"></div>
    <script type="text/javascript">
      $(function(){
        test('Multiply', function(){
          $.each([
            [[0, 2], 0],
            [[3, 3], 9],
            [[7, 9], 63]
          ], function(){
            var t = this.toString();
            equal(
              Multiply.apply(this, this[0]), this[1],
              t + ': Multiply ok'
            );
          });
        });

        test('CalculateBodyMassIndex', function(){
          this.spy(window, 'Multiply');
          $.each([
            [[1, 2], 0],
            [[10, 2], 3],
            [[35, 3], 4]
          ], function(i){
            var t = this.toString();
            equal(
              CalculateBodyMassIndex.apply(this, this[0]), this[1],
              t + ': CalculateBodyMassIndex ok'
            );
            ok(Multiply.calledOnce, t + ': call Multiply ok');
            deepEqual(
              Multiply.args[0], [this[0][1], this[0][1]],
              t + ': Multiply args ok'
            );
            Multiply.reset();
          });
        });

        test('SummAll', function(){
          $.each([
            [[1, 2, 3, 4, 5], 15],
            [[2, 3, 4, 5, 6], 20],
            [[3, 4, 5, 6, 7], 25]
          ], function(){
            var t = this.toString();
            equal(
              SummAll(this[0]), this[1],
              t + ': SummAll ok'
            );
          });
        });
      });
    </script>
  </body>
</html>

Comments

-1

It's easiest to take advantage of function scoping, and to allow optional arguments on your mockable functions:

function CalculateBodyMassIndex(weight, height, using) {
  return Math.round(weight / (using || Multiply)(height, height));
} 

Then in your test:

var MockMultiplyRan = false;
var MockMultiply = function(a,b) {
    MockMultiplyRan = true;
    return Multiply(a,b);
}

CalculateBodyMassIndex(200,200, MockMultiply); // arbitrary figures
ok(MockMultiplyRan);

1 Comment

Hi. Thanks for the answer. I am embarrassed one thing in this answer. I have to change all called CalculateBodyMassIndex in my code, haven't it? And in result I mix working logic and testing logic. I think that is wrong, because it is break solid principle. Can you explain me this moment, please?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.