Jasmine 和 Karma with Jasmine 给出了不同的结果

Jasmine and Karma with Jasmine gives different results

我最近开始在 JavaScript 中使用 Jasmine 学习单元测试。现在我在 WebStorm 工作,使用 Karma test 运行ner。当我通过控制台和 WebStorm 中的 Karma/Jasmine 对 Jasmine 进行测试时,一些结果有所不同。

例如,当我创建具有如下简化结构的项目时:

.
├── _js
|   └── script.js
├── _test
|   └── test.js
├── karma.conf.js
└── index.html

script.js

function Card(figure, color) {
    "use strict";

    var that = this;
    this.figure = figure;
    this.color = color;
    this.toString = function () {
        return that.col + that.fig;
    };
}

test.js

describe("The validation of name", function () {

    it("should return true if object is properly initialized", function () {
        var a = new Card(1,"A");
        expect(a.figure === 1)
    });

    it("should return true if array contain card", function () {
        var a = [new Card(1,"A"),new Card(1,"B"),new Card(1,"C"),new Card(1,"D")];
        console.log(a);
        expect(a).toContain({figure: 1, color: "A"});
    });
})

karma.conf.js

module.exports = function(config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine'],
    files: ['js/*.js', 'test/*.js'],
    exclude: [],
    preprocessors: {},
    reporters: ['progress'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: false,
    browsers: ['Firefox'],
    singleRun: false,
    concurrency: Infinity
  })
}

当我 运行 Jasmine 上的那些测试(HERE 在 JSFiddle 上)时,它通过了,但在 WebStorm 中它失败了,其中:

[Card{figure: 1, color: 'A', toString: function () { ... }}, Card{figure: 1, color: 'B', toString: function () { ... }}, Card{figure: 1, color: 'C', toString: function () { ... }}, Card{figure: 1, color: 'D', toString: function () { ... }}]

Expected [ NaN, NaN, NaN, NaN ] to contain Object({ figure: 1, color: 'A' }). @test/test.js:10:9 [3]http://localhost:9877/context.js:151:7

它打印来自 console.log 的正确值,但测试失败,如上所示,对象被视为 NaN。

更重要的是,如果我创建相同的对象,没有 new 关键字,通过文字对象表示法,所有测试都可以顺利通过。所以看起来构造函数在这里是个问题。

造成这种情况的原因是什么?

你的测试不会通过。

因为 toContain 检查所有对象以包含定义的属性。

所以你必须编写你的自定义匹配器。

检查这个例子:

// source code
function Card(figure, color) {
  "use strict";

  var that = this;
  this.figure = figure;
  this.color = color;
  this.toString = function () {
    return that.color + that.figure;
  };
}

var customMatchers = {
  hasObjectInArrayThatContains : function(expected){
    var arrayOfObjects = this.actual;
    // iterating array of objects and finding at least
    // one cituation where it passes test
    for(var i in arrayOfObjects) {
      var failures = 0;
      for(var key in expected) {
        if(arrayOfObjects[i][key] != expected[key]) {
          failures++;
        }
      }
      
      if(failures == 0) {
        return true;
      }
    }
    
    return false;
  } 
};

describe("The validation of name", function () {
  
  beforeEach(function(){
    this.addMatchers(customMatchers); // attaching our custom matchers
  });
  
  it("should return true if object is properly initialized", function () {
    var a = new Card(1,"A");
    expect(a.figure === 1)
  });

  it("should return true if array contain card", function () {
    var a = [new Card(1,"A"),new Card(1,"B"),new Card(1,"C"),new Card(1,"D")];
    expect(a).hasObjectInArrayThatContains({figure: 1, color: "A"}); // using our custom method
  });
});


// load jasmine htmlReporter
(function() {
  var env = jasmine.getEnv();
  env.addReporter(new jasmine.HtmlReporter());
  env.execute();
}());
<link rel="stylesheet" href="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine.css">
<script src="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine.js"></script>
<script src="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine-html.js"></script>

和失败的例子:

参见:expect(a).hasObjectInArrayThatContains({figure: 1, color: "E"})

// source code
function Card(figure, color) {
  "use strict";

  var that = this;
  this.figure = figure;
  this.color = color;
  this.toString = function () {
    return that.color + that.figure;
  };
}

var customMatchers = {
  hasObjectInArrayThatContains : function(expected){
    var arrayOfObjects = this.actual;
    // iterating array of objects and finding at least
    // one cituation where it passes test
    for(var i in arrayOfObjects) {
      var failures = 0;
      for(var key in expected) {
        if(arrayOfObjects[i][key] != expected[key]) {
          failures++;
        }
      }
      
      if(failures == 0) {
        return true;
      }
    }
    
    return false;
  } 
};

describe("The validation of name", function () {
  
  beforeEach(function(){
    this.addMatchers(customMatchers); // attaching our custom matchers
  });
  
  it("should return true if object is properly initialized", function () {
    var a = new Card(1,"A");
    expect(a.figure === 1)
  });

  it("should return true if array contain card", function () {
    var a = [new Card(1,"A"),new Card(1,"B"),new Card(1,"C"),new Card(1,"D")];
    expect(a).hasObjectInArrayThatContains({figure: 1, color: "E"}); // using our custom method
  });
});


// load jasmine htmlReporter
(function() {
  var env = jasmine.getEnv();
  env.addReporter(new jasmine.HtmlReporter());
  env.execute();
}());
<link rel="stylesheet" href="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine.css">
<script src="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine.js"></script>
<script src="https://cdn.jsdelivr.net/jasmine/1.3.1/jasmine-html.js"></script>

工作fiddle:https://jsfiddle.net/3VuGs/396/

另请阅读:testing Your js with Jasmine