当前位置:  开发笔记 > 编程语言 > 正文

RSpec嘲笑:每个块

如何解决《RSpec嘲笑:每个块》经验,为你挑选了1个好方法。

我想使用RSpec模拟为块提供固定输入.

红宝石:

class Parser
  attr_accessor :extracted

  def parse(fname)
    File.open(fname).each do |line|
      extracted = line if line =~ /^RCS file: (.*),v$/
    end
  end
end

RSpec的:

describe Parser
  before do
    @parser = Parser.new
    @lines = mock("lines")
    @lines.stub!(:each)
    File.stub!(:open).and_return(@lines)
  end

  it "should extract a filename into extracted" do
    linetext = [ "RCS file: hello,v\n", "bla bla bla\n" ]

    # HELP ME HERE ...
    # the :each should be fed with 'linetext'
    @lines.should_receive(:each)

    @parser.should_receive('extracted=')
    @parser.parse("somefile.txt")
  end
end

这是一种通过将固定数据传递到其中来测试块内部正常工作的方法.但我无法弄清楚如何使用RSpec模拟机制进行实际喂食.

更新:看起来问题不是使用linetext,而是使用:

@parser.should_receive('extracted=')

这不是它的调用方式,用红色代码替换它,self.extracted =有点帮助,但不知何故感觉不对.



1> sberkley..:

要充实"and_yield"的作用:我不认为'and_return'真的是你想要的.这将设置File.open块的返回值,而不是设置为其块的行.要略微更改示例,请说明您:

红宝石

def parse(fname)
  lines = []
  File.open(fname){ |line| lines << line*2 }
end

Rspec的

describe Parser do
  it 'should yield each line' do
    File.stub(:open).and_yield('first').and_yield('second')
    parse('nofile.txt').should eq(['firstfirst','secondsecond'])
  end
end

将传递.如果你用'and_return'代替那行

File.stub(:open).and_return(['first','second'])

它将失败,因为该块被绕过:

expected: ["firstfirst", "secondsecond"]
got: ["first", "second"]

所以底线是使用'and_yield'来模拟'each'类型块的输入.使用'and_return'来模拟这些块的输出.

推荐阅读
mobiledu2402851203
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有