I'm trying to figure out a good way to handle setting rspec memoized variables that will be cleaned up after a set of tests, but not after an individual test.
I'd like it to achieve something similar to the following, but with let or something similar that doesn't require me to be responsible for reverting the state back afterwards.
RSpec.describe person do
before(:context) do
@shared_value = create(:person)
end
after(:context) do
@shared_value.destroy
end
it "test 1" do
expect(@shared_value).to be_a(Person)
end
it "test 2" do
expect(@shared_value).to be_a(Person)
end
end
Using let! only provides a scope around each example.
Using a pattern like this raises an error for rspec
let(:shared_person)
before(:all)
shared_person
end
it "test 1" do
expect(shared_person).to be_a(Person)
end
The around method only provides a scope around each example
It's erroring because you're not defining the object... the syntax works like this:
Your code is missing the block portion defining the object, and rspec is seeing everything else you've defined after that and getting confused. Your test should look something like this:
If you aren't using FactoryBot, then your person definition would look something like:
Subject defines the object under test (making the
shouldshorthand syntax work). Unless it's necessary for the object to exist before the example runs, you should lazy load it withlet; if it's necessary for the object to exist before the example runs, then uselet!. If you need to mix them, you can do something like this:Use
contextblocks to encapsulate the test setup to simulate a specific scenario. Tests for public methods should be grouped in adescribeblock (i.e.,describe '.class_method_name' doordescribe '#instance_method_name') with 0-or-more context-specific blocks inside if it.