dry-configurable
dry-configurable copied to clipboard
Build a testing interface that doesn't require patching the test subject
RIght now, the suggested way to test configurable classes looks like this:
require "dry/configurable/test_interface"
# this is your module/class that extended by Dry::Configurable
module AwesomeModule
enable_test_interface
end
before(:all) { AwesomeModule.reset_config }
# or
before(:each) { AwesomeModule.reset_config }
I don't like this approach for several reasons:
- It requires me to add some code to my configurable class
- It makes my code less deterministic as it's different in every environment
- I just don't like using
reset
andbefore
/after
hooks
I suggest an interface that accepts a block, updates the config, then brings it back as it was.
Examples
around do |example|
stub_configurable(described_class, value_one: 1, nested_value: { key: :value }) do
example.run
end
end
If the param syntax is too complex, we can break it down to something like this:
around do |example|
stub_configurable(described_class) do |configurable|
configurable.config.value_one = 1
configurable.config.nested_value.key = :value
example.run
end
end
or just like this:
around do |example|
stub_configurable(described_class) do
described_class.config.value_one = 1
described_class.config.nested_value.key = :value
example.run
end
end
Resources
N/A
I suggest an interface that accepts a block, updates the config, then brings it back as it was.
that's literally what the test interface does, see:
def reset_config
@config = config.pristine
end
You can do it in around hook too:
around do |example|
example.run
described_class.reset_config
end
It could be extracted to an rspec-specific helper too, and provide stub_configurable
, although internally it would do the same thing as reset_config
, so I'm not sure what would be the point?
oh and btw you can just have this:
def stub_configurable(configurable)
yield(configurable)
example.run
configurable.config.update(configurable.config.pristine.to_h)
end
no extra methods required
I'm gonna close this as there was no follow-up for a while now and it doesn't seem to be a priority.