【发布时间】:2017-06-27 21:02:14
【问题描述】:
Rails 4.2 应用程序有多个模型,其属性包含 URL。 URL 验证在模型上使用validates :website_url, format: { with: /\A(https?|ftp):\/\/(-\.)?([^\s\/?\.#-]+\.?)+(\/[^\s]*)?\z/i } 完成。
我需要使用 RSpec 3.5 测试 URL 验证。重要的是要确保一些众所周知的 XSS 模式没有通过验证,并且最常用的 URL 模式通过验证。
理想情况下,我想避免为我正在测试的每个有效和无效 URL 添加一个测试,这样rspec -fd 输出就不会受到污染。但是,这可能需要创建两个测试(一个用于有效 URL,另一个用于无效 URL)并向每个测试添加多个期望(每个 URL 一个期望),这似乎不是一个好主意。
到目前为止,我想出的最佳解决方案是以下共享示例。 您能想出更好的方法来彻底测试 URL 验证吗?
RSpec.shared_examples "url validation" do |attribute|
INVALID_URLS = [
"invalidurl",
"inval.lid/urlexample",
"javascript:dangerousJs()//http://www.validurl.com",
# Literal array is required for \n to be parsed
"http://www.validurl.com\n<script>dangerousJs();</script>"
]
VALID_URLS = [
"http://validurl.com",
"https://validurl.com/blah_blah"
]
context "with invalid URLs in #{attribute}" do
INVALID_URLS.each do |url|
it "is invalid with #{url}" do
object = FactoryGirl.build(factory_name(subject), attribute => url)
object.valid?
expect(object.errors[attribute]).to include("is invalid")
end
end
end
context "with valid URLs in #{attribute}" do
VALID_URLS.each do |url|
it "is valid with #{url}" do
object = FactoryGirl.build(factory_name(subject), attribute => url)
expect(object).to be_valid
end
end
end
在模型规格内:
include_examples "url validation", :website_url
编辑:为有效和无效的 URL 添加了 context,因此 rspec -fd 输出可以更好地组织,即使大量 URL 验证测试以随机顺序执行。
【问题讨论】:
标签: ruby-on-rails ruby validation testing rspec