0

有谁知道闭包在 Mocha + Chai 测试中是如何工作的?我不确定测试运行器(在这种情况下为 phantom-js)是否搞砸了,但这没有任何意义。看起来在每个 it 功能块中创建的 var 会相互冲突。

基本上一个游戏只能有 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;
    });
4

1 回答 1

1

我看到的红旗是这样的:

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

Backbone 模型defaults附加到模型的原型上,并且浅层复制到每个实例的属性中。这样,您创建的模型的defaults每个实例最终都将共享完全相同的 PlayerCollection. 这可以解释为什么你players总是在你不期望的时候结束。

这类事情的通常解决方案是使用函数defaults

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

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

如果我的猜测是正确的,那么您的测试套件将获得胜利,因为它发现了一个隐藏且棘手的错误。

于 2014-01-06T20:58:26.207 回答