Ruby RSpec:如何模拟接受参数的对象和方法
我正在为我为Ruby RSpec:如何模拟接受参数的对象和方法,ruby,unit-testing,rspec,mocking,Ruby,Unit Testing,Rspec,Mocking,我正在为我为目录对象创建的CommandLineInterface类编写RSpec单元测试。CommandLineInterface类使用此目录对象打印出我的目录中的人员列表目录有一个#sort_by(param)方法,该方法返回字符串数组。字符串的顺序取决于传递给#sort_by方法的参数(例如,sort_by(“性别”)。在我的CLI规范中模拟此目录行为的正确方法是什么?我会使用双实例吗?我不知道对于采用参数(如按性别排序)的方法如何执行此操作 我只使用Ruby和RSpec。这里没有使用Ra
目录
对象创建的CommandLineInterface
类编写RSpec单元测试。CommandLineInterface
类使用此目录
对象打印出我的目录
中的人员列表目录
有一个#sort_by(param)
方法,该方法返回字符串数组。字符串的顺序取决于传递给#sort_by
方法的参数(例如,sort_by(“性别”)
。在我的CLI规范中模拟此目录
行为的正确方法是什么?我会使用双实例吗?我不知道对于采用参数(如按性别排序)的方法如何执行此操作
我只使用Ruby和RSpec。这里没有使用Rails、ActiveRecord等
我要模拟的类和方法的片段:
class Directory
def initialize(params)
#
end
def sort_by(param)
case param
when "gender" then @people.sort_by(&:gender)
when "name" then @people.sort_by(&:name)
else raise ArgumentError
end
end
end
这完全取决于您的对象如何协作
您的问题中缺少一些信息:
CommandLineInterface
如何使用Directory
?它是自己创建实例还是接收实例作为参数
- 您是在测试类方法还是实例方法?(首选实例方法)
如果传入依赖对象,可以这样做:
require 'rspec/autorun'
class A
def initialize(b)
@b = b
end
def foo(thing)
@b.bar(thing)
end
end
RSpec.describe A do
describe '#foo' do
context 'when given qux' do
let(:b) { double('an instance of B') }
let(:a) { A.new(b) }
it 'calls b.bar with qux' do
expect(b).to receive(:bar).with('qux')
a.foo('qux')
end
end
end
end
如果类初始化从属对象,并且知道哪个实例得到消息并不重要,则可以执行以下操作:
require 'rspec/autorun'
B = Class.new
class A
def initialize
@b = B.new
end
def foo(thing)
@b.bar(thing)
end
end
RSpec.describe A do
describe '#foo' do
context 'when given qux' do
let(:a) { A.new }
it 'calls b.bar with qux' do
expect_any_instance_of(B).to receive(:bar).with('qux')
a.foo('qux')
end
end
end
end
如果您只想删除返回值,而不想测试是否收到了确切的消息,可以使用allow
:
require 'rspec/autorun'
B = Class.new
class A
def initialize
@b = B.new
end
def foo(thing)
thing + @b.bar(thing)
end
end
RSpec.describe A do
describe '#foo' do
context 'when given qux' do
let(:a) { A.new }
it 'returns qux and b.bar' do
allow_any_instance_of(B).to receive(:bar).with('qux') { 'jabber' }
expect(a.foo('qux')).to eq('quxjabber')
end
end
end
end
粘贴实际代码会使回答更容易。