摩卡柴测试奇怪的闭合行为

时间:2014-01-04 15:45:53

标签: javascript backbone.js phantomjs mocha chai

有人知道闭合在Mocha + Chai测试中是如何工作的吗?我不确定测试运行器(在这种情况下是phantom-js)是否会弄乱,但它没有任何意义。看起来每个功能块中创建的变量都会相互冲突。

基本上一个游戏只能有10个玩家,但在每个测试中游戏变量已经有10个玩家。非常混乱。

"use strict";

CardsAgainstHumanity.module("Game", function(Game, CardsAgainstHumanity, Backbone, Marionette, $, _){
    Game.Game = Backbone.Model.extend({
        maxPlayers: 10,
        defaults: {
            players: new CardsAgainstHumanity.Player.PlayerCollection()
        },
        addPlayer: function(player){
            if(this.get("players").size() < this.maxPlayers){
                this.get("players").add(player);
            }
            else{
                throw(Error("This game is currently full"));
            }
        },
        removePlayer: function(player){
            this.get("players").remove(player);
        }
    });
});

describe.only("players can be added and removed", function(){
    it("should add a player if there is space", function(){
        var game = new CardsAgainstHumanity.Game.Game();
        var player = new CardsAgainstHumanity.Player.Player({
            id: 1
        });
        game.addPlayer(player);
        game.get("players").contains(player).should.be.true;
    });
    it("should not add a player if the game is full", function(){
        var game = new CardsAgainstHumanity.Game.Game();
        _.times(game.maxPlayers, function(index){
            var game = new CardsAgainstHumanity.Game.Game();
            game.addPlayer(new CardsAgainstHumanity.Player.Player({
               id: index
            }));
        });
        (function(){
            game.addPlayer(new CardsAgainstHumanity.Player.Player({
                id: game.maxPlayers
             }));
        }).should.throw(Error("This game is currently full"));
    });
    it("should remove said player if said player is found", function(){
        var game = new CardsAgainstHumanity.Game.Game();
        var player = new CardsAgainstHumanity.Player.Player({
            id: 1
        });
        game.addPlayer(player);
        game.get("players").contains(player).should.be.true;
        game.removePlayer(player);
        game.get("players").contains(player).should.be.false;
    });

1 个答案:

答案 0 :(得分:1)

我看到的红旗是这样的:

defaults: {
    players: new CardsAgainstHumanity.Player.PlayerCollection()
}

Backbone模型的defaults附加到模型的原型上,并被浅层复制到每个实例的属性中。使用defaults,您创建的模型的每个实例最终都会共享完全相同的 PlayerCollection。这可以解释为什么当你不期望它时players总是满满的。

此类事情的常用解决方案是使用defaults的函数:

defaults: function() {
    return {
        players: new CardsAgainstHumanity.Player.PlayerCollection()
    };
}

这样,每个实例都会获得自己唯一的默认对象,从而在其PlayerCollection属性中获得自己唯一的players。通常,只要它包含一个可变值(即数字,字符串和布尔值以外的任何值),就应该为defaults使用函数。

如果我的猜测是对的,那么你就可以获得测试套件,因为它已经发现了一个隐藏且棘手的错误。