Rails 3.1, RSpec : 모델 유효성 검사 테스트
저는 Rails에서 TDD로 여행을 시작했으며 해결책을 찾을 수없는 모델 유효성 검사 테스트와 관련하여 작은 문제에 부딪 혔습니다. 사용자 모델이 있다고 가정 해 보겠습니다.
class User < ActiveRecord::Base
validates :username, :presence => true
end
그리고 간단한 테스트
it "should require a username" do
User.new(:username => "").should_not be_valid
end
이것은 현재 상태 유효성 검사를 올바르게 테스트하지만 더 구체적으로 지정하려면 어떻게해야합니까? 예를 들어 오류 개체에서 full_messages를 테스트합니다.
it "should require a username" do
user = User.create(:username => "")
user.errors[:username].should ~= /can't be blank/
end
초기 시도 (should_not be_valid 사용)에 대한 나의 우려는 RSpec이 설명적인 오류 메시지를 생성하지 않는다는 것입니다. 단순히 "유효한 것으로 예상 되었습니까? 거짓을 반환하고 참이되었습니다."라고 말합니다. 그러나 두 번째 테스트 예제에는 사소한 단점이 있습니다. 오류 개체를 얻기 위해 새 메서드 대신 create 메서드를 사용합니다.
테스트 대상에 대해 더 구체적으로 테스트하고 싶지만 동시에 데이터베이스를 건드릴 필요가 없습니다.
누구나 의견이 있습니까?
먼저 나는 당신이 사악한 이름을 가지고 있다고 말하고 싶습니다.
둘째, ROR과 함께 TDD에 참여하신 것을 축하드립니다. 일단 가면 뒤돌아 보지 않을 것을 약속드립니다.
가장 간단하고 빠르고 더러운 해결책은 다음과 같이 각 테스트 전에 새로운 유효한 모델을 생성하는 것입니다.
before(:each) do
@user = User.new
@user.username = "a valid username"
end
그러나 내가 제안하는 것은 자동으로 유효한 모델을 생성하는 모든 모델에 대한 공장을 설정 한 다음 개별 속성을 혼동하고 유효성 검사를 확인할 수 있다는 것입니다. 나는 이것을 위해 FactoryGirl 을 사용하고 싶습니다 .
기본적으로 테스트를 설정하면 다음과 같이 보일 것입니다.
it "should have valid factory" do
FactoryGirl.build(:user).should be_valid
end
it "should require a username" do
FactoryGirl.build(:user, :username => "").should_not be_valid
end
오, 여기 저보다 더 잘 설명 하는 좋은 레일 캐스트 가 있습니다.
행운을 빕니다 :)
업데이트 : 버전 3.0 부터 factory girl의 구문이 변경되었습니다. 이를 반영하기 위해 샘플 코드를 수정했습니다.
모델 유효성 검사 (및 훨씬 더 많은 활성 레코드)를 테스트하는 더 쉬운 방법은 shoulda 또는 remarkable 과 같은 gem을 사용하는 것 입니다.
그들은 다음과 같이 테스트를 허용합니다.
describe User
it { should validate_presence_of :name }
end
이 시도:
it "should require a username" do
user = User.create(:username => "")
user.valid?
user.errors.should have_key(:username)
end
새 버전 rspec에서는 대신 expect을 사용해야합니다. 그렇지 않으면 경고가 표시됩니다.
it "should have valid factory" do
expect(FactoryGirl.build(:user)).to be_valid
end
it "should require a username" do
expect(FactoryGirl.build(:user, :username => "")).not_to be_valid
end
저는 전통적으로 기능 또는 요청 사양에서 오류 콘텐츠 사양을 처리했습니다. 예를 들어, 아래에 요약 할 비슷한 사양이 있습니다.
기능 사양 예
before(:each) { visit_order_path }
scenario 'with invalid (empty) description' , :js => :true do
add_empty_task #this line is defined in my spec_helper
expect(page).to have_content("can't be blank")
So then, I have my model spec testing whether something is valid, but then my feature spec which tests the exact output of the error message. FYI, these feature specs require Capybara which can be found here.
Like @nathanvda said, I would take advantage of Thoughtbot's Shoulda Matchers gem. With that rocking, you can write your test in the following manner as to test for presence, as well as any custom error message.
RSpec.describe User do
describe 'User validations' do
let(:message) { "I pitty da foo who dont enter a name" }
it 'validates presence and message' do
is_expected.to validate_presence_of(:name).
with_message message
end
# shorthand syntax:
it { is_expected.to validate_presence_of(:name).with_message message }
end
end
A little late to the party here, but if you don't want to add shoulda matchers, this should work with rspec-rails and factorybot:
# ./spec/factories/user.rb
FactoryBot.define do
factory :user do
sequence(:username) { |n| "user_#{n}" }
end
end
# ./spec/models/user_spec.rb
describe User, type: :model do
context 'without a username' do
let(:user) { create :user, username: nil }
it "should NOT be valid with a username error" do
expect(user).not_to be_valid
expect(user.errors).to have_key(:username)
end
end
end
참고URL : https://stackoverflow.com/questions/7537112/rails-3-1-rspec-testing-model-validations
'IT TIP' 카테고리의 다른 글
파이썬에서 sendmail을 통해 메일 보내기 (0) | 2020.10.31 |
---|---|
동적 변수 개수가있는 공식 (0) | 2020.10.31 |
R 데이터에서 이전 행의 값을 사용합니다. (0) | 2020.10.31 |
FetchMode는 SpringData JPA에서 어떻게 작동합니까? (0) | 2020.10.31 |
원격 Redis 서버에 연결하는 방법은 무엇입니까? (0) | 2020.10.31 |