我需要嘲笑以下内容:
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"]
这有效,但看起来有点笨拙,有没有更好的方法呢?
[edit]我正在使用mocha作为模拟框架
答案 0 :(得分:12)
您可以尝试这样的事情: -
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"})))
我希望有所帮助。
答案 1 :(得分: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属性的优势。