4

我需要模拟以下内容:

Class User
  def facebook
    #returns an instance of a facebook gem
  end
end

因此,在我的用户测试中,要访问用户的 facebook 信息,我需要调用user.facebook.me.info以检索其信息。如果我想模拟这个,我目前正在使用以下内容:

@user = Factory(:user)
facebook = mock()
me = mock()
me.expects(:info).returns({"name" => "John Doe"})
facebook.expects(:me).returns(me)
@user.expects(:facebook).returns(facebook)
assert_equal "John Doe", @user.facebook.me.info["name"]

这可行,但似乎有点笨拙,有没有更好的方法来做到这一点?

[编辑] 我使用 mocha 作为模拟框架

4

2 回答 2

13

你可以尝试这样的事情: -

user = Factory(:user)
user.stubs(:facebook => stub(:me => stub(:info => {:name => "John Doe"})))

如果您真的想检查是否调用了所有这些方法(我怀疑您没有),您可以执行以下操作:-

user = Factory(:user)
user.expects(:facebook => mock(:me => mock(:info => {:name => "John Doe"})))

它有点冗长,但通常值得为每个模拟对象命名:-

user = Factory(:user)
user.stubs(:facebook => stub('facebook', :me => stub('me', :info => {:name => "John Doe"})))

我希望这会有所帮助。

于 2010-12-02T13:25:10.147 回答
0

如果您不想检查是否调用了所有方法,您还可以使用不同的替代方法来模拟。例如,您可以使用 OpenStruct。

@user = Factory(:user)
facebook = mock()
me = mock()
me.expects(:info).returns({"name" => "John Doe"})
facebook.expects(:me).returns(me)
@user.expects(:facebook).returns(facebook)
assert_equal "John Doe", @user.facebook.me.info["name"]

变成

@user = Factory(:user)
@facebook = OpenStruct.new(:me => OpenStruct.new(:info => {:name => "John Doe"}))
@user.expects(:facebook).returns(@facebook)

如果您需要测试不同的条件,此解决方案还为您提供了可以在测试中更改 @facebook 属性的优势。

于 2010-12-02T13:32:54.653 回答