2011-09-14 6 views
29

ActiveRecord에서 다음 유효성 검사를 수행합니다.RSpec을 사용하여 Rails에서 포함 검증을 테스트하려면 어떻게해야합니까?

validates :active, :inclusion => {:in => ['Y', 'N']} 

다음을 사용하여 모델 유효성 검사를 테스트하고 있습니다.

should_not allow_value('A').for(:active) 
should allow_value('Y').for(:active) 
should allow_value('N').for(:active) 

더 깨끗하고 더 많은 테스트 방법이 있습니까? 나는 현재 RSpec2와 shoulda matchers를 사용하고있다.

편집 난 단지,이 테스트의이 아마 '확인'방법은, 했어야 그것을 위해 자신의 사용자 정의 정규 표현을 쓸 수 필요이 아무것도 누군가를 제공하지 않습니다 발견 둘러보고 일부 후

(아마도 프로젝트에 다시 기여할 것입니다). 어떤 사람이 토론 할 수있는 링크 :

  • 위의 내용을 나타내는 링크. Link 1, Link 2

  • should_ensure_value_in_range이 하나를 사용할 수 있습니다 무엇에 근접 있지만 범위와하지의 값 목록을 허용합니다. 사용자 정의 일치 프로그램은이를 기반으로 할 수 있습니다.

    예 :

    it { should validate_inclusion_check_constraint_on :status, :allowed_values => %w(Open Resolved Closed) } 
    it { should validate_inclusion_check_constraint_on :age, :allowed_values => 0..100 } 
    

    매처

답변

53

사용 shoulda_matchers 적어도 V2.7의 같은 shoulda-matchers의 최신 버전 (에서

.0)을 수행 할 수 있습니다 :

expect(subject).to validate_inclusion_of(:active).in_array(%w[Y N]) 

이 검증에 사용할 수있는 값의 배열이 정확히 사양과 일치하는지 테스트합니다. 이전 버전의

,> = V1.4, shoulda_matchers이 구문을 지원합니다

it {should ensure_inclusion_of(:active).in_array(%w[Y N]) } 
+0

다른 값을 허용하지 않는지 확인하려면 다음과 같이하면됩니다 :'it {should_not allow_value ('?') for (: active)}'- 당신이 말한 것처럼 가능한 모든 값을 검사 할 수는 없지만 허용 된 모든 값을 확인하는 것 외에 합리적인 적용 범위처럼 보입니다. – bjnord

+0

당신이 ** 언급 한 shoulda_matcher는 ** 원래의 설명대로 작동합니다. 즉 제공된 배열에없는 값을 사용할 수 없습니다. [문서 참조] (https://github.com/thoughtbot/shoulda-matchers#ensure_inclusion_of). 좋은 측정을 위해, 나는 이것을 Rails 앱에서 테스트했고 올바르게 작동한다. –

+1

@LarsLevie - 의견을 주셔서 감사합니다. 그들은'disallows_value_outside_of_array? '를 확인하기 위해 유효성 검사를 변경 한 것 같습니다. 이전 https://github.com/thoughtbot/shoulda-matchers/blob/v1.2.0/lib/shoulda/matchers/active_model/ensure_inclusion_of_matcher.rb#L86 vs now https://github.com/thoughtbot/shoulda- matchers/blob/15abdf066732828034efea751c2937aa81d080fe/lib/shoulda/matchers/active_model/ensure_inclusion_of_matcher.rb # L90 –

1

나는 이런 식으로 뭔가를 테스트 가까이 오기 시도 (내가 작업 한 프로젝트 중 하나에서) 하나 개의 사용자 정의 했어야의 정규 발견 저장을 시도 할 때 폭발하는 DB 제약이 있는지 확인하려고합니다. 아이디어의 핵심을 제공하려고 시도합니다. 성냥? 구현은 같은 작업을 수행합니다

begin 
    @allowed_values.each do |value| 
     @subject.send("#{@attribute}=", value) 
     @subject.save(:validate => false) 
    end 
    rescue ::ActiveRecord::StatementInvalid => e 
    # Returns false if the exception message contains a string matching the error throw by SQL db 
    end 

우리가 약간 @subject.save 말과 예외 문자열이 가까운 실제 예외 오류 메시지가 일치하는 것을 포함 된 경우 레일의 유효성 검사가 폭파, 우리는 false를 반환 할 수 있도록 위를 변경하는 경우 것 같아요.

이 프로젝트에 기여하는 데는 완벽하지 않습니다. 실제로 :inclusion 유효성 검사를 많이 테스트하려는 경우 프로젝트를 사용자 지정 matcher로 추가하는 것이 좋지 않을 수도 있습니다.

+0

나는 아무 것도 찾을 수가 없기 때문에 여기에 내 자신의 대답에 동의하지만 어떻게 비판 주시기 바랍니다 것입니다 위의 해결책은 실패 할 수 있습니다. – jake

23

테스트 할 요소가 부울 Y/N보다 많으면 시도해 볼 수 있습니다. 그것은 단지 상수 값이 허가되는 것을 테스트 있도록

it "should allow valid values" do 
    %w(item1 item2 item3 item4).each do |v| 
    should allow_value(v).for(:field) 
    end 
end 
it { should_not allow_value("other").for(:role) } 

당신은 또한 당신의 모델에서 정의한 상수로 %w()를 교체 할 수 있습니다.

CONSTANT = %w[item1 item2 item3 item4] 
validates :field, :inclusion => CONSTANT 

그런 다음 테스트 :

it "should allow valid values" do 
    Model::CONSTANT.each do |v| 
    should allow_value(v).for(:field) 
    end 
end 
관련 문제