ruby-on-rails - 使用 RSpec 构建 TDD/BDD 帮助

标签 ruby-on-rails ruby rspec tdd bdd

大约两周前,我开始学习 Ruby,我使用“open-uri”和“nokogiri”制作了一个 WebParser/Page WordCounter。所以我只是用 'ruby counter.rb http://test.com 运行终端word' 和 i 以及该单词的匹配数,不区分大小写,这样我就可以抓取所有内容。

所以我在这里学习 RSpec、TDD、BDD 和所有这些东西,我想知道如何使用 RSpec 示例和期望构建我的代码。我已经阅读了所有文档,我正在构建简单的示例来测试等。

我想知道是否有人可以将我的代码构建到 RSpec 示例和期望中,以便我可以研究您所做的事情以及如何完成。

这是我的代码:

require 'open-uri'
require 'nokogiri'

class Counter   

    def initialize(url)
      @url = url
    end

    def count(word, url)
      doc = Nokogiri::HTML(open(url))
      doc.css('head').remove
      doc.text.scan(/#{word}/i).size
    end
end

url, word = ARGV
puts "Found: #{Counter.new(url).count(word, url)} matches."

希望有人能帮助我,我真的很喜欢 ruby​​ 并且发现这个 RSpec 很棒,

谢谢大家,我会学习并等待!

最佳答案

有一个 rspec --init 命令可以创建您的样板文件。

完成此操作后,打开 spec_helper.rb 并需要您的代码文件。

顺便说一下,你的初始化接受一个 url 并将其分配给一个实例变量,但 count 方法接受一个 url 作为参数,这有点奇怪。

所以假设它被重构为:

attr_reader :url
def initialize(url)
  @url = url
end

def count(word)
  doc = Nokogiri::HTML(open(url)) # this uses the attr_reader
  doc.css('head').remove
  doc.text.scan(/#{word}/i).size
end

然后你可以编写一个像这样的测试用例(这不是全面的覆盖,只是一个例子):

describe "Counter" do
  let(:url) { "http://some_url" }
  let(:counter) { Counter.new url }
  it "counts words" do
    expect(counter.count("foo")).to(
      eq("<whatever the expected result is>")
    )
  end
end

使用 let 设置变量是可选的。您还可以在 it ... do block 内设置变量,但您必须针对每种情况重复它。

除了.to之外,还有.not_to,除了eq之外,还有许多其他有用的方法。我建议阅读 RSpec 匹配器文档来熟悉这些。

还值得一提的是,该测试用例将进行 HTTP 调用,有时需要,有时不需要。例如,如果您有很多案例并希望快速运行它们,那么删除 HTTP 调用将是有益的。但这样做意味着您不再实际测试 url 的状态。如果标记发生变化怎么办?除非您的测试用例实际进行 HTTP 调用,否则您无法确定。

不过,了解如何删除 HTTP 调用还是有好处的,因为底层概念(“mocking”或“stubbing”)有很多用途。像这样的事情:

  it "counts words" do
    mock_html = <<-HTML
      <!doctype html>
      <html lang='en'>
        <head></head>
        <body>foo</body>
      </html>
    HTML
    expect(Object).to(
      receive(:open).with(any_args).at_least(1).times.and_return(mock_html)
    )
    expect(counter.count("foo")).to eq(1)
    expect(counter.count("bar")).to eq(0)
  end

any_args 是一个特殊术语,可以在 stub 方法时使用。您还可以在此处使用 url,因为您知道传递的参数是什么。

有关更多信息,我将再次向您推荐 RSpec 的文档,这次是有关模拟/ stub 的文档。

通常,您希望主要关注函数的输入/输出。有时您会想要检查是否调用了另一个方法(为此您将使用模拟/ stub ),但可能不希望您测试每一行代码。

关于ruby-on-rails - 使用 RSpec 构建 TDD/BDD 帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42125263/

相关文章:

mysql - 如何在 rails 中对 4 个表使用连接查询

ruby - 当值用作 Object.const_get 的参数时,无法将 Configatron::Store 转换为字符串错误

ruby - 拦截对不存在的方法的调用

ruby-on-rails - cucumber 和 rails : testing for the presence of a random record

ruby-on-rails - 为什么不能在 Controller 测试中使用路由器路径?

ruby-on-rails - Capybara 单次测试配置

mysql - 如何在第三个表上匹配两种记录

mysql - 更新时,如果我的参数之一为空,如何从数据库中删除它?

ruby-on-rails - 编辑插入新记录

ruby-on-rails - Rails 4,使用 ActiveRecord 的原始查询