[RUBY-ON-RAILS] (액티브) 개체 평등을 테스트하는 방법
RUBY-ON-RAILS(액티브) 개체 평등을 테스트하는 방법
레일 3.0.3에 루비 1.9.2, 난 (액티브 :: 자료에서 클래스 상속) 두 친구 사이의 개체 평등에 대한 테스트를 시도하고있어 객체.
개체는 동일하지만, 테스트가 실패합니다 :
Failure/Error: Friend.new(name: 'Bob').should eql(Friend.new(name: 'Bob'))
expected #<Friend id: nil, event_id: nil, name: 'Bob', created_at: nil, updated_at: nil>
got #<Friend id: nil, event_id: nil, name: 'Bob', created_at: nil, updated_at: nil>
(compared using eql?)
그냥 싱긋 웃음을 위해, 나는 또한 예상대로 실패 개체 식별을위한 테스트 :
Failure/Error: Friend.new(name: 'Bob').should equal(Friend.new(name: 'Bob'))
expected #<Friend:2190028040> => #<Friend id: nil, event_id: nil, name: 'Bob', created_at: nil, updated_at: nil>
got #<Friend:2190195380> => #<Friend id: nil, event_id: nil, name: 'Bob', created_at: nil, updated_at: nil>
Compared using equal?, which compares object identity,
but expected and actual are not the same object. Use
'actual.should == expected' if you don't care about
object identity in this example.
누군가는 개체 평등에 대한 첫 번째 테스트가 실패 이유를 나에게 설명 할 수, 나는 그 두 개체가 동일한 성공적으로 할 수 있습니다 주장하는 방법?
해결법
-
==============================
1.식별 컬럼에 의도적으로 위임 평등 검사를 레일. 두 AR 오브젝트가 같은 물건을 포함하는 경우 알고 싶다면, 모두 #attributes를 호출 한 결과를 비교합니다.
식별 컬럼에 의도적으로 위임 평등 검사를 레일. 두 AR 오브젝트가 같은 물건을 포함하는 경우 알고 싶다면, 모두 #attributes를 호출 한 결과를 비교합니다.
-
==============================
2.==의 API 문서에 (별칭 EQL?)를 봐 작업을 액티브을 위해 :: 자료를
==의 API 문서에 (별칭 EQL?)를 봐 작업을 액티브을 위해 :: 자료를
-
==============================
3.아이디, created_at 및 updated_at : 당신이 그 속성에 따라 두 모델 인스턴스를 비교하려는 경우, 당신은 아마 같은 당신의 비교에서 특정 관련이없는 속성을 제외 할 것입니다. (나는 그 레코드의 데이터 자체의 부분보다 기록에 대한 자세한 메타 데이터로 간주합니다.)
아이디, created_at 및 updated_at : 당신이 그 속성에 따라 두 모델 인스턴스를 비교하려는 경우, 당신은 아마 같은 당신의 비교에서 특정 관련이없는 속성을 제외 할 것입니다. (나는 그 레코드의 데이터 자체의 부분보다 기록에 대한 자세한 메타 데이터로 간주합니다.)
경우 =이 힘은 중요하지 당신이 (ID, created_at 때문에, 구원까지 updated_at 모든 전무 할 것이다) 두 개의 새로운 (저장되지 않은) 기록을 비교할 때,하지만 때로는 필요 (저장되지 않은 하나에 저장된 객체를 비교 찾을 수 = 전무하기 때문에 당신에게 거짓을 줄 것이다! = 5). 아니면 내가 (그들은 그렇지 않으면 동일한 경우에도 액티브 == 작업자가 작업을하지 않도록 서로 다른 ID의이있는 경우 false를 반환하기 때문에,)가 같은 데이터가 포함되어 있는지 확인하기 위해 두 저장된 객체를 비교합니다.
이 문제에 대한 나의 해결책은 당신이 속성을 사용하여 비교되고 싶어하는 모델이 뭔가를 추가하는 것입니다 :
def self.attributes_to_ignore_when_comparing [:id, :created_at, :updated_at] end def identical?(other) self. attributes.except(*self.class.attributes_to_ignore_when_comparing.map(&:to_s)) == other.attributes.except(*self.class.attributes_to_ignore_when_comparing.map(&:to_s)) end
그럼 내 사양에 나는이 같은 읽기 쉽고 간결 일을 쓸 수 있습니다 :
Address.last.should be_identical(Address.new({city: 'City', country: 'USA'}))
나는 active_record_attributes_equality 보석을 분기이 더 쉽게 재사용 할 수 있도록이 동작을 사용 변경에 대한 계획입니다.
내가 가진 몇 가지 질문은,하지만, 다음과 같습니다 :
댓글은 환영합니다 ...
업데이트 : 대신 active_record_attributes_equality을 분기, 나는 http://github.com/TylerRick/active_record_ignored_attributes 및 http://rubygems.org/gems/active_record_ignored_attributes에서 사용할 수있는 아주 새로운 보석, active_record_ignored_attributes을 썼다
-
==============================
4.
META = [:id, :created_at, :updated_at, :interacted_at, :confirmed_at] def eql_attributes?(original,new) original = original.attributes.with_indifferent_access.except(*META) new = new.attributes.symbolize_keys.with_indifferent_access.except(*META) original == new end eql_attributes? attrs, attrs2
-
==============================
5.난 그냥 비교, 매우 간단하지만 효과적인 이러한 유형의 RSpec에에 정규를 만들었습니다.
난 그냥 비교, 매우 간단하지만 효과적인 이러한 유형의 RSpec에에 정규를 만들었습니다.
이 파일 내부 : 사양 / 지원 / matchers.rb
당신은이 정규 표현을 구현할 수 ...
RSpec::Matchers.define :be_a_clone_of do |model1| match do |model2| ignored_columns = %w[id created_at updated_at] model1.attributes.except(*ignored_columns) == model2.attributes.except(*ignored_columns) end end
다음과 같은 방법에 의해, 스펙을 작성할 때 그 후, 당신은 그것을 사용할 수 있습니다 ...
item = create(:item) # FactoryBot gem item2 = item.dup expect(item).to be_a_clone_of(item2) # True
유용한 링크:
https://relishapp.com/rspec/rspec-expectations/v/2-4/docs/custom-matchers/define-matcher https://github.com/thoughtbot/factory_bot
from https://stackoverflow.com/questions/4738439/how-to-test-for-activerecord-object-equality by cc-by-sa and MIT license
'RUBY-ON-RAILS' 카테고리의 다른 글
[RUBY-ON-RAILS] 창을 사용하여 레일에 JSON 보석을 설치할 수 없습니다 (0) | 2020.02.16 |
---|---|
[RUBY-ON-RAILS] rescue_from ActionController :: RoutingError 레일 4 (0) | 2020.02.16 |
[RUBY-ON-RAILS] 루비 2.4과 너무 깊이 레일 4 스택 레벨 (SystemStackError) (0) | 2020.02.16 |
[RUBY-ON-RAILS] 액티브 레코드 테이블에 대량 삽입 기록 (0) | 2020.02.16 |
[RUBY-ON-RAILS] 왜 사용 HTTP의 PUT 대신 POST의 DELETE 방법? (0) | 2020.02.16 |