복붙노트

[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. ==============================

    1.식별 컬럼에 의도적으로 위임 평등 검사를 레일. 두 AR 오브젝트가 같은 물건을 포함하는 경우 알고 싶다면, 모두 #attributes를 호출 한 결과를 비교합니다.

    식별 컬럼에 의도적으로 위임 평등 검사를 레일. 두 AR 오브젝트가 같은 물건을 포함하는 경우 알고 싶다면, 모두 #attributes를 호출 한 결과를 비교합니다.

  2. ==============================

    2.==의 API 문서에 (별칭 EQL?)를 봐 작업을 액티브을 위해 :: 자료를

    ==의 API 문서에 (별칭 EQL?)를 봐 작업을 액티브을 위해 :: 자료를

  3. ==============================

    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. ==============================

    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. ==============================

    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

  6. from https://stackoverflow.com/questions/4738439/how-to-test-for-activerecord-object-equality by cc-by-sa and MIT license