Rails 4.2アプリケーションには、URLを含む属性を持つモデルがいくつかあります。 URL検証はvalidates :website_url, format: { with: /\A(https?|ftp):\/\/(-\.)?([^\s\/?\.#-]+\.?)+(\/[^\s]*)?\z/i }
のモデルで実行されます。RSpecによるURL(正規表現)検証のテスト
RSpec 3.5でURL検証をテストする必要があります。いくつかのよく知られているXSSパターンが検証に合格しないこと、そして最も一般的に使用されるURLパターンが検証に合格することを確認することが重要です。
rspec -fd
の出力が汚染されないように、理想的には、私がテストしている有効で無効なURLごとに1つのテストを追加することを避けたいと思います。しかし、おそらく2つのテスト(有効なURL用と無効なURL用)を作成し、各テストに複数の期待を追加する必要があります(URLあたり1つの期待)。
私が今までに思いついた最善の解決策は、次の共有例です。 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の検証テストの数が多いので、rspec -fd
出力をよりよく組織化され、有効と無効なURLのcontext
を追加しました注文。
ご回答ありがとうございます。私も試したが、オブジェクトの作成を繰り返すことを避けることができませんでした。同じshared_examplesブロック内であっても、ループ内のURLを 'let'ブロックに渡すのは面倒でした。 – BrunoFacca
@BrunoFacca明確にするために、あなたのユースケースでは上記の解決策が使えますか?問題がある場合は教えてください。 –
それは動作します。しかし、このように分割するメリット(3つの共有例を作成する)を説明してください。このアプローチは賢明で洗練されていますが、反復やLOCを減らすことなく複雑さを増やしてくれます。あなたの経験からすれば、私はおそらく何かを欠いているでしょう。 – BrunoFacca