thoughtbot--factory_bot/spec/acceptance/build_stubbed_spec.rb

282 lines
6.9 KiB
Ruby

describe "a generated stub instance" do
include FactoryBot::Syntax::Methods
before do
define_model("User")
define_model("Post", title: :string,
body: :string,
age: :integer,
user_id: :integer,
draft: :boolean) do
belongs_to :user
end
FactoryBot.define do
factory :user
factory :post do
title { "default title" }
body { "default body" }
user
end
end
end
subject { build_stubbed(:post, title: "overridden title") }
it "assigns a default attribute" do
expect(subject.body).to eq "default body"
end
it "assigns an overridden attribute" do
expect(subject.title).to eq "overridden title"
end
it "assigns associations" do
expect(subject.user).to be_kind_of(User)
end
it "has an id" do
expect(subject.id).to be > 0
end
it "generates unique ids" do
other_stub = build_stubbed(:post)
expect(subject.id).not_to eq other_stub.id
end
it "isn't a new record" do
expect(subject).not_to be_new_record
end
it "assigns associations that aren't new records" do
expect(subject.user).not_to be_new_record
end
it "isn't changed" do
expect(subject).not_to be_changed
end
it "disables connection" do
expect { subject.connection }.to raise_error(RuntimeError)
end
it "disables update_attribute" do
expect { subject.update_attribute(:title, "value") }.to raise_error(RuntimeError)
end
it "disables reload" do
expect { subject.reload }.to raise_error(RuntimeError)
end
it "disables destroy" do
expect { subject.destroy }.to raise_error(RuntimeError)
end
it "disables save" do
expect { subject.save }.to raise_error(RuntimeError)
end
it "disables increment!" do
expect { subject.increment!(:age) }.to raise_error(RuntimeError)
end
it "disables decrement!" do
expect { subject.decrement!(:age) }.to raise_error(RuntimeError)
end
it "disables toggle!" do
expect { subject.toggle!(:draft) }.to raise_error(RuntimeError)
end
it "allows increment" do
subject.age = 1
subject.increment(:age)
expect(subject.age).to eq(2)
end
it "allows decrement" do
subject.age = 1
subject.decrement(:age)
expect(subject.age).to eq(0)
end
it "allows toggle" do
subject.draft = true
subject.toggle(:draft)
expect(subject).not_to be_draft
end
end
describe "calling `build_stubbed` with a block" do
include FactoryBot::Syntax::Methods
before do
define_model("Company", name: :string)
FactoryBot.define do
factory :company
end
end
it "passes the stub instance" do
build_stubbed(:company, name: "thoughtbot") do |company|
expect(company.name).to eq("thoughtbot")
expect { company.save }.to raise_error(RuntimeError)
end
end
it "returns the stub instance" do
expected = nil
result = build_stubbed(:company) do |company|
expected = company
"hello!"
end
expect(result).to eq expected
end
end
describe "defaulting `created_at`" do
include FactoryBot::Syntax::Methods
before do
define_model("ThingWithTimestamp", created_at: :datetime)
define_model("ThingWithoutTimestamp")
FactoryBot.define do
factory :thing_with_timestamp
factory :thing_without_timestamp
end
end
it "defaults created_at for objects with created_at" do
expect(build_stubbed(:thing_with_timestamp).created_at).to be_about_now
end
it "is doesn't mark the object as changed" do
stub = build_stubbed(:thing_with_timestamp)
expect(stub).not_to be_changed
end
it "doesn't add created_at to objects who don't have the method" do
expect(build_stubbed(:thing_without_timestamp)).
not_to respond_to(:created_at)
end
it "allows overriding created_at for objects with created_at" do
created_at = 3.days.ago
stubbed = build_stubbed(:thing_with_timestamp, created_at: created_at)
expect(stubbed.created_at).to eq created_at
end
it "doesn't allow setting created_at on an object that doesn't define it" do
expect { build_stubbed(:thing_without_timestamp, created_at: Time.now) }.
to raise_error(NoMethodError, /created_at=/)
end
it "allows assignment of created_at" do
stub = build_stubbed(:thing_with_timestamp)
expect(stub.created_at).to be_about_now
past_time = 3.days.ago
stub.created_at = past_time
expect(stub.created_at).to eq past_time
end
it "behaves the same as a non-stubbed created_at" do
define_model("ThingWithCreatedAt", created_at: :datetime) do
def created_at
:the_real_created_at
end
end
FactoryBot.define do
factory :thing_with_created_at
end
stub = build_stubbed(:thing_with_created_at)
persisted = create(:thing_with_created_at)
expect(stub.created_at).to eq(persisted.created_at)
end
end
describe "defaulting `updated_at`" do
include FactoryBot::Syntax::Methods
before do
define_model("ThingWithTimestamp", updated_at: :datetime)
define_model("ThingWithoutTimestamp")
FactoryBot.define do
factory :thing_with_timestamp
factory :thing_without_timestamp
end
end
it "defaults updated_at for objects with updated_at" do
expect(build_stubbed(:thing_with_timestamp).updated_at).to be_about_now
end
it "is doesn't mark the object as changed" do
stub = build_stubbed(:thing_with_timestamp)
expect(stub).not_to be_changed
end
it "doesn't add updated_at to objects who don't have the method" do
expect(build_stubbed(:thing_without_timestamp)).
not_to respond_to(:updated_at)
end
it "allows overriding updated_at for objects with updated_at" do
past_time = 3.days.ago
stubbed = build_stubbed(:thing_with_timestamp, updated_at: past_time)
expect(stubbed.updated_at).to eq past_time
end
it "doesn't allow setting updated_at on an object that doesn't define it" do
expect do
build_stubbed(:thing_without_timestamp, updated_at: Time.now)
end.to raise_error(NoMethodError, /updated_at=/)
end
it "allows assignment of updated_at" do
stub = build_stubbed(:thing_with_timestamp)
expect(stub.updated_at).to be_about_now
past_time = 3.days.ago
stub.updated_at = past_time
expect(stub.updated_at).to eq past_time
end
it "behaves the same as a non-stubbed updated_at" do
define_model("ThingWithUpdatedAt", updated_at: :datetime) do
def updated_at
:the_real_updated_at
end
end
FactoryBot.define do
factory :thing_with_updated_at
end
stub = build_stubbed(:thing_with_updated_at)
persisted = create(:thing_with_updated_at)
expect(stub.updated_at).to eq(persisted.updated_at)
end
end
describe "defaulting `id`" do
before do
define_model("Post")
FactoryBot.define do
factory :post
end
end
it "allows overriding id" do
expect(FactoryBot.build_stubbed(:post, id: 12).id).to eq 12
end
end