Mik*_*yth 66 testing rspec ruby-on-rails stub
我有一个模型Family,location它有一个合并location其他对象的成员的方法,成员.(成员与家庭有关,但这在这里并不重要.)
例如,给定
location=='圣地亚哥(旅游,5月15日返回)'location=='圣地亚哥'Family.location可能会返回'圣地亚哥(member_1旅行,5月15日返回)'细节不重要.
为了简化Family.location的测试,我想要存根Member.location.但是,我需要它返回两个不同的(指定的)值,如上例所示.理想情况下,这些将基于属性member,但只是在序列中返回不同的值就可以了.在RSpec有办法做到这一点吗?
可以在每个测试示例中覆盖Member.location方法,例如
it "when residence is the same" do
class Member
def location
return {:residence=>'Home', :work=>'his_work'} if self.male?
return {:residence=>'Home', :work=>'her_work'}
end
end
@family.location[:residence].should == 'Home'
end
Run Code Online (Sandbox Code Playgroud)
但我怀疑这是好习惯.在任何情况下,当RSpec运行一系列示例时,它不会恢复原始类,因此这种覆盖"毒药"后续示例.
那么,有没有办法让stubbed方法在每次调用时返回不同的指定值?
idl*_*ers 145
您可以将方法存根以在每次调用时返回不同的值;
allow(@family).to receive(:location).and_return('first', 'second', 'other')
Run Code Online (Sandbox Code Playgroud)
因此,第一次调用@family.location它将返回'first',第二次返回'second',以及随后所有调用它,它将返回'other'.
not*_*ere 13
RSpec 3语法:
allow(@family).to receive(:location).and_return("abcdefg", "bcdefgh")
Run Code Online (Sandbox Code Playgroud)
仅当您有特定数量的调用并需要特定的数据序列时,才应使用已接受的解决方案。但是,如果您不知道将进行的调用次数,或者不关心数据的顺序只是每次都不同,该怎么办?正如 OP 所说:
简单地在序列中返回不同的值就可以了
问题and_return在于返回值被记忆。这意味着即使你返回一些动态的东西,你也会得到相同的结果。
例如
allow(mock).to receive(:method).and_return(SecureRandom.hex)
mock.method # => 7c01419e102238c6c1bd6cc5a1e25e1b
mock.method # => 7c01419e102238c6c1bd6cc5a1e25e1b
Run Code Online (Sandbox Code Playgroud)
或者一个实际的例子是使用工厂并获得相同的 ID:
allow(Person).to receive(:create).and_return(build_stubbed(:person))
Person.create # => Person(id: 1)
Person.create # => Person(id: 1)
Run Code Online (Sandbox Code Playgroud)
在这些情况下,您可以存根方法体以每次都执行代码:
allow(Member).to receive(:location) do
{ residence: Faker::Address.city }
end
Member.location # => { residence: 'New York' }
Member.location # => { residence: 'Budapest' }
Run Code Online (Sandbox Code Playgroud)
请注意,您无法self在此上下文中访问 Member 对象,但可以使用测试上下文中的变量。
例如
member = build(:member)
allow(member).to receive(:location) do
{ residence: Faker::Address.city, work: member.male? 'his_work' : 'her_work' }
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
28025 次 |
| 最近记录: |