Bersihkan pencocokan Rspec untuk perubahan(Model, :count).by(1)

Saya bekerja keras untuk menjaga file spesifikasi saya sebersih mungkin. Menggunakan permata 'seharusnya' dan menulis pencocokan khusus yang mengikuti pola yang sama.

Pertanyaan saya adalah tentang membuat pencocokan khusus yang akan membungkus expect{ post :create ... }.to change(Model, :count).by(1) dan dapat digunakan dalam grup contoh yang sama dengan pencocokan 'seharusnya' lainnya. Detail di bawah:

Pencocokan khusus (disederhanakan)

RSpec::Matchers.define :create_a_new do |model|
  match do |dummy|
    ::RSpec::Expectations::ExpectationTarget.new(subject).to change(model, :count).by(1)
  end
end

Contoh kerja

describe 'POST create:' do
  describe '(valid params)' do
    subject { -> { post :create, model: agency_attributes } }
    it { should create_a_new(Agency) }
  end
end

Ini berfungsi dengan baik selama saya menggunakan lambda subject dan pencocokan saya adalah satu-satunya di grup contoh.

Contoh yang gagal

Contoh gagal 1

Menambahkan lebih banyak contoh dalam grup yang sama membuat pencocokan lainnya gagal karena subject sekarang menjadi lambda dan bukan turunan dari Pengendali.

describe 'POST create:' do
  describe '(valid params)' do
    subject { -> { post :create, model: agency_attributes } }
    it { should create_a_new(Agency) }
    it { should redirect_to(Agency.last) }
  end
end

Contoh gagal 2

Pencocokan 'seharusnya' mengharapkan saya untuk mendefinisikan blok before, tetapi ini menjadi tidak kompatibel dengan pencocokan khusus saya

describe 'POST create:' do
  describe '(valid params)' do
    before { post :create, agency: agency_attributes }
    it { should create_a_new(Agency) }
    it { should redirect_to(Agency.last) }
  end
end

Hasil yang diharapkan

Saya mencari cara untuk menulis pencocokan khusus saya yang sesuai dengan grup contoh yang sama dengan pencocokan lainnya, artinya pencocokan khusus saya harus menggunakan blok before untuk menjalankan tindakan pengontrol, "contoh gagal #2" di atas adalah cara saya ingin menulis spesifikasi saya. Apa itu mungkin?

Terima kasih sudah membaca


person Benj    schedule 02.08.2013    source sumber


Jawaban (1)


Saya rasa tidak ada cara agar contoh gagal Anda bisa lolos.

Ini karena change benar-benar membutuhkan lambda, karena ia perlu melakukan penghitungan dua kali (sekali sebelum, dan sekali setelah memanggilnya). Itulah alasan saya cenderung tidak menggunakannya (atau menggunakannya dalam isolasi konteks).

Apa yang biasanya saya lakukan, daripada menggunakan count matcher, adalah memeriksa tiga hal:

  • Rekor tersebut masih bertahan. Jika saya menetapkan model ke @model, maka saya menggunakan expect(assigns(:model)).to be_persisted
  • Catatan tersebut merupakan contoh dari model yang diharapkan (walaupun mungkin tidak berguna, namun cukup deskriptif ketika menggunakan IMS). expect(assigns(:model)).to be_a(Model).
  • Periksa catatan terakhir di DB sama dengan yang baru saja saya buat `expect(assigns(:model)).to eq(Model.last)``

Dan begitulah biasanya saya menguji change matcher tanpa menggunakannya. Tentu saja, kini Anda dapat membuat pencocokan Anda sendiri

RSpec::Matchers.define :create_a_new do |model|
  match do |actual|
    actual.persisted? &&
      actual.instance_of?(Participant) &&
      (Participant.last == actual)
  end
end
person Serabe    schedule 04.08.2013
comment
Menarik, terima kasih atas klarifikasinya. Izinkan saya mengujinya sedikit dan saya akan kembali bersama Anda. - person Benj; 05.08.2013
comment
Hal lain yang saya coba akhir-akhir ini adalah merangkum tindakan (post :create, params, session) dalam suatu metode. Belum yakin apakah saya akan terus melakukannya, namun untuk beberapa kasus, mungkin ada gunanya. - person Serabe; 05.08.2013
comment
Itu juga salah satu percobaan saya set(:action) {post :create ...} tetapi saya tidak menemukan cara untuk menjadi benar-benar KERING, karena saya mendapatkan kode yang berbau seperti before { unless example.metadata[:skip_before]; action end } - person Benj; 05.08.2013
comment
Ada cara dengan around hooks, tapi itu berarti menjalankan ekspektasi di setiap contoh, dan menurut saya itu bukan yang Anda inginkan. - person Serabe; 06.08.2013
comment
Maaf karena meluangkan waktu saya untuk menjawab, saya belum memeriksanya tetapi sepertinya hal yang benar untuk dilakukan, saya akan mengujinya nanti kapan pun saya punya waktu untuk melakukannya. Terima kasih atas tipnya - person Benj; 11.08.2013