如何根据茉莉花单元测试中的其他对象测试功能

时间:2012-05-25 07:31:00

标签: javascript unit-testing backbone.js jasmine sinon

我有一个名为Event的骨干模型的茉莉花单元测试。

在这个模型中,我有一个功能:

getParticipants: function(){
  new Myappp.Collections.UsersCollection(
    this.get("participations").map(function(participation){
      return participation.get("user");
    });
  );
}

它有4个依赖项:

  • 用户模型
  • 用户集合
  • 参与模式
  • 参与集合

我想单独测试所有模型,因为这是最佳实践,但我不确定如何。

我正在使用sinon.js进行模拟和存根,但在这种情况下不知道如何正确使用它。

谢谢!

1 个答案:

答案 0 :(得分:4)

你的方法getParticipants正在做很多事情......实际上是3件事,所以我宁愿把它集中在一件事上:构建Myappp.Collections.UsersCollection。并将之前所需的所有计算移至另一种方法。

然后你可以专注于一个非常棘手的问题:模仿new电话

我分3个阶段完成:

1。将用户过滤器移动到另一个地方

我建议将其移至Myapp.Collections.ParticipationsCollection中的方法,然后我们可以从我们的Event实例中调用它,如下所示:

Myapp.Models.Event = 
  Backbone.Model.extend({
    getParticipants: function(){
      var usersArray   = this.get("participations").getUsers();
      var participants = new Myapp.Collections.UsersCollection(usersArray);

      return participants;
    }
  });

Myapp.Collections.ParticipationsCollection = 
  Backbone.Collection.extend({
    getUsers: function(){
      var users = 
        this.map(function(participation){
          return participation.get("user");
        });

      return users;
    }
  });

这样我们就可以轻松模拟 getUsers方法来测试我们的目标方法。

2。包含用户数组获取

,甚至更多

我上面的代码示例我们在行this.get("participations").getUsers()中仍然有一个复杂的链式方法调用我们可以将它移动到一个易于模拟的自定义方法:

我们完成了这样的事情:

Myapp.Models.Event = 
  Backbone.Model.extend({
    getParticipants: function(){
      var usersArray   = this.getUsersArray();
      var participants = new Myapp.Collections.UsersCollection( usersArray );

      return participants;
    },

    getUsersArray: function(){
      return this.get("participations").getUsers();
    }
  });

3。测试集合初始化

现在我们必须专注于模拟集合Myapp.Collections.UsersCollection,并检查我们的方法初始化和使用正确的参数集合的实体。

正确的参数是方法Event.getUsersArray()的结果,现在我们可以轻松地模拟它。

Sinon特别期望检查是否已使用new调用方法..

我的Jasmine / Sinon方法并不准确,因为我没有测试该方法是否返回 new 集合,我希望有人可以提供更好的实现:

describe("Event", function() {
  beforeEach(function(){
    testModel = new Myapp.Models.Event();
  });

  it("getParticipants returns proper Collection", function() {
    var usersCollectionSpy = sinon.spy( Myapp.Collections, "UsersCollection" );

    var getUsersArrayMock = sinon.stub(testModel, "getUsersArray");
    getUsersArrayMock.returns( "usersArray" );

    testModel.getParticipants();

    expect( usersCollectionSpy.calledWith( "usersArray" ) ).toBeTruthy();
    expect( usersCollectionSpy.calledWithNew() ).toBeTruthy();
  });
});

Check the jsFiddle