Cukup hijau untuk pengujian, tetapi saya mengikuti kursus udemy sederhana. Saya menggunakan dokumentasi RSpec untuk mengatur RSpec di Rails untuk mencoba beberapa pengujian. Tetapi saya telah menemukan masalah yang seumur hidup saya tidak dapat saya pahami...

require "rails_helper"

RSpec.describe User, type: :model do
  subject { described_class.new("John") }

  it "initializes a name" do
    expect(subject.name).to eq("John")
  end

  context "with no argument" do
    subject { described_class.new }

    it "should default to Bill as the name" do
      expect(subject.name).to eq("Bill")
    end
  end
end

# This is my test code. 

# This is my User model. 

class User < ApplicationRecord
  attr_reader :name

  def initialize(name = "Bill")
    @name = name
  end
end

Ketika saya menjalankan tes itu gagal dan mengatakan bahwa tes kedua tidak mengembalikan Bill tetapi 'nihil'. Namun, dalam model Pengguna saya jika saya menghapus < Rekam Aplikasi yang dilewatinya... Juga, jika saya menambahkan parameter kedua di inisialisasi, itu secara acak melewati tes default dan gagal yang pertama mengembalikan nama default... I' saya benar-benar bingung karena saya telah mempelajari pengujian tanpa ApplicationRecord dan itu tampaknya menjadi bagian yang gagal. Saya telah mencoba mengubah subjek menjadi let(:testing){User.new} tetapi tidak berhasil. Bantuan apa pun sangat dihargai di sini karena sepertinya saya tidak dapat menemukannya melalui google.

Untuk memberi tahu Anda bahwa saya memiliki permata 'rspec-rails', '~> 4.0.0' yang disertakan dalam GemFile saya di bagian :development, :test.

0
Tigiras 6 Juli 2020, 16:20

1 menjawab

Jawaban Terbaik

Anda mencoba mengganti penginisialisasi default model dan Anda melakukannya dengan cara yang salah. Saat Anda memanggil new di kelas ActiveRecord, Anda harus meneruskan hash parameter. Untuk memiliki bidang name dalam model, Anda perlu mendefinisikannya dalam skema DB.

Pembuatan instance User untuk kasus uji pertama akan terlihat seperti ini:

described_class.new(name: "John")

Saya melihat cara-cara ini untuk memiliki nilai default untuk suatu atribut:

Setel menggunakan callback

class User < ApplicationRecord
  after_initialize :set_name

  private

  def set_name
    self.name ||= 'Bill' # Set name to Bill if it is nil
  end
end

Ganti metode initialize.

# Please avoid this approach
class User < ApplicationRecord
  def initialize(*args)
    super # This will initiate default behaviour of a model
    self.name ||= 'Bill' 
  end
end

Menggunakan atribut API seperti yang disarankan @engineersmnky

class User < ApplicationRecord
  attribute :name, :string, default: 'Bill'
end

Saya sangat menyarankan menggunakan pendekatan callback atau atribut API untuk tidak merusak perilaku default.

Setelah itu, tes Anda harus lulus saya percaya.

2
Yakov 6 Juli 2020, 14:24