Αποτυχία του RSpec have_attributes με argument matchers

Γιατί, όταν χρησιμοποιούμε το have_attributes με πολλούς argument matchers και αποτυγχάνει μόνο ένας, το RSpec αποτυγχάνει και όλους τους υπόλοιπους;

Δημοσιεύτηκε · 154 λέξεις · Προβολή ως Markdown


Γιατί, όταν χρησιμοποιούμε το have_attributes με πολλούς argument matchers και αποτυγχάνει μόνο ένας, το RSpec αποτυγχάνει και όλους τους υπόλοιπους;

Παράδειγμα κώδικα#

Ruby
require 'rspec'

Customer = Struct.new(:id, :name)

RSpec.describe 'fail' do
  subject { Customer.new(123, 'Some Name') }

  it 'fails' do
    expect(subject).to have_attributes(
      id: kind_of(String),
      name: kind_of(String)
    )
  end
end

Αποτυχία#

Failing spec with have_attributes & kind_of

Παρότι μόνο το id είναι άκυρο, βλέπουμε και τα δύο, :name και :id, ως αποτυχημένα.

Γιατί;#

Όταν έρθει η ώρα να εμφανίσει τα αποτελέσματα της αποτυχίας, το RSpec κάνει diff ανάμεσα στις αναμενόμενες και τις πραγματικές τιμές. Για να κάνει diff σε αντικείμενα, χρησιμοποιεί τον RSpec::Support::Differ, ο οποίος τα μετατρέπει σε strings κάνοντας inspect.

Εφόσον χρησιμοποιούμε τον argument matcher RSpec::Mocks::ArgumentMatchers::KindOf, το RSpec τον ταιριάζει με τον
RSpec::Support::ObjectFormatter::DescribableMatcherInspector και έτσι παίρνουμε το kind of String.

Μπορείς να το αναπαράγεις τρέχοντας:

Ruby
RSpec::Support::ObjectFormatter::DescribableMatcherInspector.new(
  RSpec::Mocks::ArgumentMatchers::KindOf.new(String)
).inspect

Όταν έρθει η ώρα να συγκριθούν τα diffs, συγκρίνουμε το kind of String με το Some Name και καταλήγουμε στο κόκκινο output σφάλματος, παρότι ο matcher δεν απέτυχε για το συγκεκριμένο attribute.

Εδώ υπάρχει ένα Github issue για αυτό.