Skip to content

Instantly share code, notes, and snippets.

@palkan
Last active July 11, 2023 17:21
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save palkan/bf2c983ac9bfa701223fc0a87d273de7 to your computer and use it in GitHub Desktop.
Save palkan/bf2c983ac9bfa701223fc0a87d273de7 to your computer and use it in GitHub Desktop.
[AnyFixture] shared account
require "test_prof/any_fixture/dsl"
require "test_prof/ext/active_record_refind"
using TestProf::AnyFixture::DSL
using TestProf::Ext::ActiveRecordRefind
shared_context "feature account", type: :feature do
prepend_before(:all) do
account = fixture(:account) do
build(:account,
name: 'Star Wars',
slug: "sw").tap do |acc|
acc.owner = build :user,
email: 'dw@sw.spec', name: 'Darth Vader',
password: 'theforce',
password_confirmation: 'theforce',
owner: true
acc.default_brand = build(:brand, name: 'Paranoid Droid', slug: 'paranoid-droid')
acc.save!
end
end
brand = fixture(:brand) { @account.default_brand }
fixture(:vader) { @account.owner }
location_group = fixture(:location_group) do
create :location_group, name: "Arkanis", account: account
end
location = fixture(:location) do
create :location, name: "Tatooine",
account: account, group: location_group,
brand: brand,
country_code: 'VU' # Vanuatu; they eat humans!
end
position = fixture(:position) do
create :position, account: account, name: "Stormtrooper"
end
funnel = fixture(:funnel) do
create(:funnel, :with_stages, :with_active_campaign,
account: account,
location: location,
position: position,
title: "#{location.name} - #{position.name}").tap do |f|
create(:stage, funnel: f, title: 'Welcome to Death Star')
end
end
landing_stage = funnel.stages(true).find { |s| s.title == 'Welcome to Death Star' }
luke = fixture(:luke) do
create(
:applicant, stage: landing_stage,
name: 'Luke Skywalker', email: 'luke@sw.spec',
key: 'luke-1'
)
end
fixture(:luke_identity) do
create(
:portal_applicant, full_name: 'Luke Skywalker',
first_name: 'Luke', last_name: 'Skywalker',
email: 'luke@sw.spec',
password: 'theforce',
password_confirmation: 'theforce'
).tap do |ident|
ident.applicants << luke
end
end
fixture(:finn) do
create(
:applicant, stage: landing_stage,
name: 'Finn', email: 'fn2187@sw.spec',
key: 'fn-2187'
)
end
end
# Ensure that every example has a fresh copy of a record
%i[
account brand funnel stage position location location_group
vader luke luke_identity finn
].each do |id|
let(id) { fixture(id).refind }
end
end
@varunlalan
Copy link

Is there a way to refer already created fixture in a new fixture?
Considering above example - can we create a shared_context 'user' and use that user fixture instead of line 13 where we are initializing a new user object?

@palkan
Copy link
Author

palkan commented Apr 8, 2022

Is there a way to refer already created fixture in a new fixture?

Yes, you can use fixture(:user) (w/o a block) for that. Note that the :user fixture has to be already defined.

@varunlalan
Copy link

Is there a way to refer already created fixture in a new fixture?

Yes, you can use fixture(:user) (w/o a block) for that. Note that the :user fixture has to be already defined.

The :user fixture need to be in same shared_context or it can refer another in different file? Can you share an example?

@palkan
Copy link
Author

palkan commented Apr 8, 2022

It could be defined anywhere but must be populated before you use it

@varunlalan
Copy link

I created a file shared_user.rb in path spec/support/shared_contexts, and created another file shared_attachment.rb in the same path. Now, when I call fixture(:user) inside shared_attachment.rb, it gives me error: *** LocalJumpError Exception: no block given (yield). What am I missing here?

@palkan
Copy link
Author

palkan commented Apr 12, 2022

You should include shared_user before (or inside) shared_attachment; this error means that no fixture has been registered.

@aelkoussy
Copy link

Thanks @palkan - is there an equivalent for shared_context of Rspec in Minitest?
I tried to use this AnyFixture but unfortunately the fixture is cleared/deleted after first case is ran

(i.e with a test of 5 cases, 1st one calls the fixture correctly, but then it is deleted and other cases can't reuse it) - since you have Minitest in the guide I thought maybe I missed something?

Thank you

@palkan
Copy link
Author

palkan commented Jul 11, 2023

Hey @aelkoussy!

In Minitest, you can use Ruby modules to share functionality. However, you're likely need smth like before(:all) / after(:all)—that can be achieved through some patching. See our Minitest before_all integration, for example: https://github.com/test-prof/test-prof/blob/17d674dfe9bbccab45a436f64bb1e1cc774e8572/lib/test_prof/recipes/minitest/before_all.rb#L158-L172

@aelkoussy
Copy link

Hey @palkan, thanks a lot! :) I will give it a try, I tried the gem https://github.com/jeremyevans/minitest-hooks and tried setting the fixture in a before(:all) block but it was always removed after first test... to keep it as simple I defined the fixture in a before(:all) in the same test file but it works for 1 test and for others the fixture is not found

I thought I missed something but given your comment, I am now suspecting something custom in our code is clearing the database after each test - will check and thanks for the great work! 🎉

I will try to add more info here if I find a solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment