我应该如何避免使用Sinon.js存根属性

mic*_*ael 5 javascript sinon

我发现Sinon不会让你存根属性,只有方法.我正试图弄清楚如何处理/拥抱这个.

我有以下代码:

var Player = {
  addPoints: function(points) {
    this.score += points;
  },
  score: 0
}

var Game = {
  setPlayers: function(players) {
    this.players = players;
  },
  over: function() {
    return this.players.some(function(player) {
      return player.score >= 100;
    });
  },
}
Run Code Online (Sandbox Code Playgroud)

这是我写的一个测试:

describe("Game", function() {
  it("is over if a player has at least 100 points", function() {
    var game = Object.create(Game);
    player = Object.create(Player);
    game.setPlayers([player]);
    player.addPoints(100);
    game.over().should.be.true;
  });
});
Run Code Online (Sandbox Code Playgroud)

感觉不对的我不得不去和呼出addPoints()Player时候我测试Game.我最初的本能是存根Player.points,但我不能这样做,因为Sinon只存根属性,而不是方法.

我该怎么想这个?

mic*_*ael 7

我通过电子邮件发送了SinonJS邮件列表,作者回信说:

完全像你做过.直接写入score属性完全违背了addPoints方法的目的,并使您的测试与实现紧密耦合(从而使其变得脆弱).

如果您确实想要"存根"该属性,请按以下步骤操作:

describe("Game", function() {
  it("is over if a player has at least 100 points", function() { 
    var game = Object.create(Game); 
    player = Object.create(Player); 
    game.setPlayers([player]); 
    player.score = 100; 
    game.over().should.be.true;
  });
});
Run Code Online (Sandbox Code Playgroud)

它是一个实例上的属性 - 没有必要过于聪明.我仍然建议你不要这样做.


And*_*rle 4

您不必存根,game.points只需设置它即可。因此,您可以创建一个简单的模拟Game,它只是object该方法的一个间谍setPlayer。然后你可以score在测试中设置你想要的内容。

describe("Game", function() {
  var game;

  before(function(){
    game = {addPoints: jasmine.createSpy()}
  })

  it("is over if a player has at least 100 points", function() { 
    game.score = 100;
    player = Object.create(Player);
    game.setPlayers([player]);
    game.over().should.be.true;
  });
});
Run Code Online (Sandbox Code Playgroud)