dry-configurable icon indicating copy to clipboard operation
dry-configurable copied to clipboard

Build a testing interface that doesn't require patching the test subject

Open Morozzzko opened this issue 5 years ago • 2 comments

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:

  1. It requires me to add some code to my configurable class
  2. It makes my code less deterministic as it's different in every environment
  3. I just don't like using reset and before/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

Morozzzko avatar Feb 12 '20 15:02 Morozzzko

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?

solnic avatar Feb 15 '20 17:02 solnic

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

solnic avatar Feb 15 '20 17:02 solnic

I'm gonna close this as there was no follow-up for a while now and it doesn't seem to be a priority.

solnic avatar Sep 20 '22 03:09 solnic