【问题标题】:How can I use mock in my js tests?如何在我的 js 测试中使用 mock?
【发布时间】:2012-06-10 11:56:38
【问题描述】:

我尝试使用 QUnit 来测试我的 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;

}

我有两个问题: 1)我如何验证函数CalculateBodyMassIndex将被称为乘法函数?

2) 我如何验证函数 SummAll 是否会从 jQuery 库中调用 $.each?

感谢等待答复。

【问题讨论】:

    标签: javascript jquery testing qunit sinon


    【解决方案1】:

    只需粘贴以下 html 并从浏览器中打开即可。

    <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>
    

    【讨论】:

      【解决方案2】:

      这是一篇关于如何将 sinon.js 与 QUnit 一起用于模拟 http://cjohansen.no/en/javascript/using_sinon_js_with_qunit 的精彩帖子。

      sinon 中的间谍和存根允许您非常轻松地验证对现有对象的调用。

      编辑 此处http://sinonjs.org/docs/#spies 的 sinon.js 文档展示了如何使用 Spies。浏览完整的 API 文档以获取存根、模拟等示例。

      【讨论】:

      • 嗨。感谢您的回答和链接。我有第二个问题。如果我想确保使用特定参数调用该函数,我应该如何编写测试?不幸的是,我在文章中找不到示例。
      【解决方案3】:

      利用函数作用域以及在可模拟函数上允许可选参数是最简单的:

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

      然后在你的测试中:

      var MockMultiplyRan = false;
      var MockMultiply = function(a,b) {
          MockMultiplyRan = true;
          return Multiply(a,b);
      }
      
      CalculateBodyMassIndex(200,200, MockMultiply); // arbitrary figures
      ok(MockMultiplyRan);
      

      【讨论】:

      • 嗨。感谢您的回答。我在这个答案中感到尴尬一件事。我必须在我的代码中更改所有名为 CalculateBodyMassIndex 的内容,不是吗?结果我混合了工作逻辑和测试逻辑。我认为这是错误的,因为它是打破坚实的原则。请你在这一刻给我解释一下好吗?
      猜你喜欢
      • 2016-07-15
      • 2023-04-09
      • 1970-01-01
      • 2022-10-23
      • 2017-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-14
      相关资源
      最近更新 更多