Rails 4.2应用程序有几个模型,其中包含包含URL的属性。网址验证在模型中使用validates :website_url, format: { with: /\A(https?|ftp):\/\/(-\.)?([^\s\/?\.#-]+\.?)+(\/[^\s]*)?\z/i }
完成。
我需要使用RSpec 3.5测试URL验证。确保一些众所周知的XSS模式不通过验证并且最常用的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
修改:为有效和无效的网址添加了context
,以便rspec -fd
输出更有条理,即使以随机顺序执行了大量的网址验证测试。
答案 0 :(得分:1)
你的解决方案并不糟糕。我继续使用更多shared_examples
:
RSpec.shared_examples "an invalid URL for attribute" do |url, attribute|
let(:object) { FactoryGirl.build(factory_name(subject), attribute => url) }
before(:each) { object.valid? }
specify { expect(object.errors[attribute]).to include("is invalid") }
end
RSpec.shared_examples "a valid URL for attribute" do |url, attribute|
let(:object) { FactoryGirl.build(factory_name(subject), attribute => url) }
specify { expect(object).to be_valid }
end
RSpec.shared_examples "URL validation" do |attribute|
[ "invalidurl",
"inval.lid/urlexample",
# ...
].each do |url|
it_behaves_like "a valid URL for attribute", url, attribute
end
[ "http://validurl.com",
"https://validurl.com/blah_blah"
].each do |url|
it_behaves_like "an invalid URL for attribute", url, attribute
end
end
重复的let(:object)
让我感到困惑,但我没有立即解决这个问题。