1

我有一个名为 Event 的主干模型的 jasmine 单元测试。

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

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

它有 4 个依赖项:

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

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

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

谢谢!

4

1 回答 1

4

你的方法getParticipants做了很多事情..实际上是三件事,所以我宁愿尝试让它专注于一件事情:构建Myappp.Collections.UsersCollection. 并将所有先前需要的计算移至其他方法。

然后你可以专注于非常棘手的一个:模拟newcall

我会分三个阶段进行:

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.测试Collection初始化

现在我们必须专注于模拟 CollectionMyapp.Collections.UsersCollection并检查我们的初始化方法和这个 Collection 的实体是否具有正确的参数。

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

Sinon 有一个特别的期望,就是检查一个方法是否被new..调用过。

我的 Jasmine/Sinon 方法不是很准确,因为我没有测试该方法是否返回的Collection,我希望有人能提供更好的实现:

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();
  });
});

检查 jsFiddle

于 2012-05-28T19:43:47.597 回答