Ruby 如何使用Rspec 3.4根据用户输入存根/模拟多个选项

Ruby 如何使用Rspec 3.4根据用户输入存根/模拟多个选项,ruby,unit-testing,rspec,mocking,rspec3,Ruby,Unit Testing,Rspec,Mocking,Rspec3,我是Rspec的新手,这是我第一次尝试在rails框架之外进行测试。我只是想了解,当我的应用程序的实现相当复杂时,我如何能够模仿它的行为 我希望能够模拟调用customize\u gender输入选项的行为,并检查输入1时结果是否为“男性”,输入2时结果是否为“女性”,等等 我还希望能够检查@gender的实例变量是否设置正确,这就是为什么我首先添加了attr\u reader:gender。我一直在尝试一些事情,但我想我不明白mock在一般情况下是如何找到解决方案的。我看过类似的问题,但它们似

我是Rspec的新手,这是我第一次尝试在rails框架之外进行测试。我只是想了解,当我的应用程序的实现相当复杂时,我如何能够模仿它的行为

我希望能够模拟调用
customize\u gender
输入选项的行为,并检查输入1时结果是否为“男性”,输入2时结果是否为“女性”,等等

我还希望能够检查
@gender
的实例变量是否设置正确,这就是为什么我首先添加了
attr\u reader:gender
。我一直在尝试一些事情,但我想我不明白mock在一般情况下是如何找到解决方案的。我看过类似的问题,但它们似乎不适合我的场景。非常感谢您的任何见解

主文件(person.rb)

Rspec文件(spec/person\u spec.rb)


下面是如何实现的,这里唯一被模拟的是
get
被设置为“1”(记住在本例中它是一个字符串,因为
get
输入始终是一个字符串)

对于
when 3
,您可以使用以下命令

RSpec.describe Person do
  subject { Person.new }

  it 'returns other as gender when other has been entered' do
    allow(subject).to receive(:gets).and_return('3', 'other')
    subject.customize_gender

    expect(subject.gender).to eq('other')
  end
end

这适用于简单的情况,但是嵌套的get在
when 3
子句中如何呢?有没有办法模拟一下?我只是想找出一种方法来优雅地适应所有的边缘情况。我的意思是,是的,当用户输入
3
时,它应该适用于第一种情况。但如果用户输入3,则会立即要求用户输入他选择的其他性别。例如,流程如下:
enter3->enter'other'->结果应该是'other'
Perfect!这正是我想要的。我将把它标记为已解决,但这是一个简单的问题。这与
allow(subject.).to receive(:get).execute(2).times.和_return('3','Other')
)之间有什么区别吗?您可以使用
.execute(2).times.和_return
expect
(例如,确保调用的次数不会超过该次数)。试着用
expect(subject).to receive(:get).execute(3).times.和_return('3','Other')
来代替,并观察结果。是的,我从名字haha得到了这个。我只是想确定一下。谢谢你的帮助!:D
require_relative "../person"
describe Person do
    let(:person) { Person.new }
    allow(Person).to receive(:gets).and_return(1,2,3)
    person.customize_gender
    expect(person.gender).to eq 'Male'
    # allow(person).to receive(:customize_gender).and_return('Male')
    # expect(Person).to receive(:puts).with('What is your gender?')
    # allow(Person).to receive(:gets) { 1 }
    # expect(person.gender).to eq 'Male'
end
RSpec.describe Person do
  subject { Person.new }

  it 'returns male as gender when male is chosen' do
    allow(subject).to receive(:gets).and_return('1')
    subject.customize_gender

    expect(subject.gender).to eq('Male')
  end
end
RSpec.describe Person do
  subject { Person.new }

  it 'returns other as gender when other has been entered' do
    allow(subject).to receive(:gets).and_return('3', 'other')
    subject.customize_gender

    expect(subject.gender).to eq('other')
  end
end