I’m looking for the best way to work with container stubs in tests. My current main issue is with unstubbing and how to make it both convenient and reliable. I’m using RSpec. I see 3 possible approaches, but they all have their downsides.
1. Unstub all in after(:each)
This is a simple, where in the rspec config you put:
config.after(:each) do
Slice1::Container.unstub
Slice2::Container.unstub
end
It has a clear upside that it works for all tests and I don’t need to remember to unstub manually, similarly to database cleaning. It shares the downside of db cleaning as well - seems to be small. For my not-so-big test suite of 45 tests it causes a slowdown of about 40%.
2. Only use blocks
Instead of caring for unstubbing, perhaps I could just only use block syntax in tests?
it "tests with a stub" do
fake_repo = double("repo")
Slice1::Container.stub("repositories.account", fake_repo) do
response = Slice1::Actions::Verify.call({id: 1})
expect(response.flash[:success]).to eq(...)
end
end
The problem here is that stub
with a block lacks ensure
- if the expectation fails, the container is not unstubbed and leaks to other tests. Perhaps this is something that could be fixed upstream in dry-container
?
3. Unstub in after
block per test case
Last approach is to just manually unstub whenever I use stubbing, so:
RSpec.describe "something" do
after do
Slice1::Container.unstub("repositories.account")
end
it "does something with a stub" do
Slice1::Container.stub("repositories.account", something)
# ...
end
end
It works best so far, but is also most verbose. Of course, I could abstract it out to some helper method, which - maybe - could just unstub everything.
But I wonder what are the preferred approaches to work with stubs in the community.