如果使用rspec-mocks,您可以使用partial test double 存根对MyGem.search 的方法调用。
部分测试替身是系统中真实对象的扩展
在测试的上下文中类似 test-double 的行为。这种技术在 Ruby 中很常见
因为我们经常看到类对象充当方法的全局命名空间。
将MyGem 部分加倍并期望调用其search 类方法:
expect(MyGem).to receive(:search)
然后你可以在这个双重上添加额外的行为到check the call arguments,使它成为yield values,或者raise an error:
# match arguments
expect(MyGem).to receive(:search).with(:attributes => ["displayname", "employeeID"])
# yield value
expect(MyGem).to receive(:search).and_yield(42)
# yield multiple values
expect(MyGem).to receive(:search).and_yield(42).and_yield(987)
# raise an error
expect(MyGem).to receive(:search).and_raise(ArgumentError, "bad request")
# all at once!
expect(MyGem).to receive(:search).with(:attributes => ["displayname", "employeeID"])
.and_yield(42)
.and_raise(ArgumentError, "bad request")
根据您的信息(似乎不完整:dept 参数从未使用过...),这是一个完整的示例:
Entry = Struct.new(:employeeid, :displayname)
class MyGem
def self.search(*args)
yield Entry.new([1, 2, 3], ["one", "two", "three"])
end
end
class Organization
def search(*args, &blk)
MyGem.search(*args, &blk)
end
def members_of(dept)
result = {}
search(:attributes => ["displayname", "employeeID"]) do |entry|
result[entry.employeeid.first.to_i] = entry.displayname.first.to_s
end
result
rescue
[]
end
end
RSpec.describe Organization do
describe "#members_of" do
it "calls search" do
organization = Organization.new
expect(MyGem).to receive(:search).with(:attributes => ["displayname", "employeeID"])
.and_yield(Entry.new([1337, 100, 2000], ["leet", "one hundred", "two thousand"]))
.and_yield(Entry.new([123], ["one-two-three"]))
members = organization.members_of("dept")
expect(members).to match({
1337 => "leet",
123 => "one-two-three"})
end
it "returns empty array on search error" do
organization = Organization.new
expect(MyGem).to receive(:search).and_raise(ArgumentError)
expect(organization.members_of("dept")).to eq([])
end
end
end
另外,当使用部分双精度时,您应该启用verify_partial_doubles 配置选项以确保您不会存根不存在的类方法。在 spec/spec_helper.rb 文件中使用这个 sn-p 启用它:
RSpec.configure do |config|
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
end