在Rails单元测试中使用带有regex的assert_match

时间:2015-10-01 15:49:47

标签: ruby-on-rails regex railstutorial.org

我正在研究Rails教程第11章前2

本教程要求通过替换FILL_IN变量来检查微博的数量(可以是任何数字)来完成测试

  test "micropost sidebar count" do
    log_in_as(@user)
    get root_path
    assert_match "#{FILL_IN} microposts", response.body
    # User with zero microposts
    other_user = users(:mallory)
    log_in_as(other_user)
    get root_path
    assert_match "0 microposts", response.body
    other_user.microposts.create!(content: "A micropost")
    get root_path
    assert_match FILL_IN, response.body
  end

在第一个FILL_IN中,我在任一数字/^[1-9]\d*$/的正则表达式中添加并尝试通过将其分配给变量进行插值,如下所示

regex_number = /^[1-9]\d*$/
assert_match "#{regex_number } microposts", response.body

这对我不起作用(我的灯具的响应体中有34个微博)

我使用工具检查了正则表达式,应该匹配34

最后一件事,你怎么检查像micropost这样的复数的匹配 这是因为最终的FILL_IN用于“1微博”

2 个答案:

答案 0 :(得分:8)

在本练习中,您不应该使用正则表达式。但是,让我们一步一步地采取行动:

首先,我不认为正则表达式会在引号中起作用。插值后,您的代码将显示为assert_match "/^[1-9]\d*$/ microposts", response.body。对于assert_match,您要么需要正则表达式或字符串匹配,而不是两者。您应该删除插值,删除引号,并放置'微博'在正则表达式内部。

其次,我认为你的正则表达式已被打破。 ' ^'匹配字符串的开头,' $'匹配字符串的结尾,但assert_match正在将你的正则表达式与只有一个字符串进行比较:主页的整个主体!你并不关心匹配的位置,只要它存在于字符串的某个地方。这使得开始和结束锚点不适合该搜索。

这是通过此测试的正则表达式版本:

assert_match(/[1-9]\d microposts/, response.body)

但这对于此测试要完成的内容来说过于通用。您不想在页面上查找任何数字。您希望在“微博”字样之前查找正确的微博数量。

环顾网络,这就是大多数人为此练习完成FILL_IN的方式:

assert_match "#{@user.microposts.count} microposts", response.body

assert_match "#{other_user.microposts.count} micropost", response.body

有些人甚至只是简单地填写他们希望测试找到的数字,而不是查看用户对象的数字,但我认为这太容易打破,可能不是Hartl想要的。

至于Pluralize ......我抨击这个问题很长一段时间。经过多次痛苦之后,我终于找到了两种方法。老实说,我不认为Hartl打算让我们在这个测试中使用它,因为他之前从未在测试中使用它。我认为他打算让我们直接在搜索字符串中输入正确的复数,如上所示。

无论如何,如果你真的想这样做,有两种方法可以用复数方法完成第二个FILL_IN:

assert_match "#{other_user.microposts.count} micropost".pluralize(other_user.microposts.count), response.body

assert_match ActionController::Base.helpers.pluralize(other_user.microposts.count, "micropost"), response.body

在实践中,您可能希望通过执行以下操作来提高可读性:

num = other_user.microposts.count
assert_match "#{num} micropost".pluralize(num), response.body

答案 1 :(得分:1)

有趣的是,您选择尝试使用REGEX来解决此问题。虽然我没有示例的答案,但我还是以不同的方式解决了第一个FILL_IN问题 - 利用同一章节前面的integration / user_profile_test.rb文件中的学习。您是否因任何特殊原因选择了REGEX路线?

至于第二个FILL_IN,我想你可能会过度思考它 - 答案可以从你上面转录的Hartl提供的“微博边栏数”代码中推断出来。 ; - )