Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/svoop/minitest-substitute
Substitute values for the duration of a block or a group of tests.
https://github.com/svoop/minitest-substitute
minitest ruby
Last synced: 7 days ago
JSON representation
Substitute values for the duration of a block or a group of tests.
- Host: GitHub
- URL: https://github.com/svoop/minitest-substitute
- Owner: svoop
- License: mit
- Created: 2023-08-19T14:49:23.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2024-03-26T19:43:55.000Z (8 months ago)
- Last Synced: 2024-10-04T07:22:51.131Z (about 1 month ago)
- Topics: minitest, ruby
- Language: Ruby
- Homepage:
- Size: 146 KB
- Stars: 4
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Funding: .github/FUNDING.yml
- License: LICENSE.txt
Awesome Lists containing this project
README
[![Version](https://img.shields.io/gem/v/minitest-substitute.svg?style=flat)](https://rubygems.org/gems/minitest-substitute)
[![Tests](https://img.shields.io/github/actions/workflow/status/svoop/minitest-substitute/test.yml?style=flat&label=tests)](https://github.com/svoop/minitest-substitute/actions?workflow=Test)
[![Code Climate](https://img.shields.io/codeclimate/maintainability/svoop/minitest-substitute.svg?style=flat)](https://codeclimate.com/github/svoop/minitest-substitute/)
[![GitHub Sponsors](https://img.shields.io/github/sponsors/svoop.svg)](https://github.com/sponsors/svoop)# Minitest::Substitute
Simple Minitest helper to replace values such as an instance variable of an object or an environment variable for the duration of a block or a group of tests.
This comes in very handy when you have to deviate from default configuration in order to test some aspects of your code.
* [Homepage](https://github.com/svoop/minitest-substitute)
* [API](https://www.rubydoc.info/gems/minitest-substitute)
* Author: [Sven Schwyn - Bitcetera](https://bitcetera.com)Thank you for supporting free and open-source software by sponsoring on [GitHub](https://github.com/sponsors/svoop) or on [Donorbox](https://donorbox.com/bitcetera). Any gesture is appreciated, from a single Euro for a ☕️ cup of coffee to 🍹 early retirement.
## Install
This gem is [cryptographically signed](https://guides.rubygems.org/security/#using-gems) in order to assure it hasn't been tampered with. Unless already done, please add the author's public key as a trusted certificate now:
```
gem cert --add <(curl -Ls https://bitcetera.com/downloads/gem-public_cert.pem)
```Add the following to the Gemfile or gems.rb of your [Bundler](https://bundler.io) powered Ruby project:
```ruby
gem 'minitest-substitute'
```And then install the bundle:
```
bundle install --trust-policy MediumSecurity
```Finally, require this gem in your `test_helper.rb` or `spec_helper.rb`:
```ruby
require 'minitest/substitute'
```## Update from 0.x.x to 1.x.x
Rails 7 has polluted `Object` for everybody by introducing `Object#with`. To prevent collisions, Minitest::Substitute has switched from `with` to `substitute` as of version 1.0.0.
After having updated this gem, you'll have to adapt all your tests accordingly:
```ruby
# Version 0.x.x
with '@version', 2, on: config do
config.instance_variable_get('@version') # => 2
end# Version 1.x.x
substitute '@version', 2, on: config do
config.instance_variable_get('@version') # => 2
end
```## Usage
### Block
To substitute the value of an instance variable for the duration of a block:
```ruby
class Config
def initialize
@version = 1
end
endconfig = Config.new
config.instance_variable_get('@version') # => 1
substitute '@version', 2, on: config do
config.instance_variable_get('@version') # => 2
end
config.instance_variable_get('@version') # => 1
```:warning: The target `on` is set explicitly in this case. If you omit this argument, `self` will be used as target by default.
Class variables can be substituted as well:
```ruby
class Config
@@counter = 0
endConfig.class_variable_get('@@counter') # => 0
substitute '@@counter', 42, on: Config do
Config.class_variable_get('@@counter') # => 42
end
Config.class_variable_get('@@counter') # => 0
```Same goes for global variables:
```ruby
$verbose = false # => false
substitute '$verbose', true do
$verbose # => true
end
$verbose # => false
```And it works for globals like `ENV` as well which comes in handy when you have to temporarily override the value of an environment variable:
```ruby
ENV['EDITOR'] # => 'vi'
substitute "ENV['EDITOR']", 'nano' do
ENV['EDITOR'] # => 'nano'
end
ENV['EDITOR'] # => 'vi'
```You can even substitute constants, however, you have to use their absolute name starting with `::`:
```ruby
module Animals
DOG_MAKES = 'woof'
CAT_MAKES = 'meow'
endAnimals::DOG_MAKES # => 'woof'
substitute '::Animals::DOG_MAKES', Animals::CAT_MAKES do
Animals::DOG_MAKES # => 'meow'
end
Animals::DOG_MAKES # => 'woof'
```Remember that class declarations are assigned to constants as well:
```ruby
class Dog
self.makes
'woof'
end
endclass Cat
self.makes
'meow'
end
endDog.makes # => 'woof'
substitute '::Dog', Cat do
Dog.makes # => 'meow'
end
Dog.makes # => 'woof'
```It's safe to nest multiple `substitute` statements.
### Group of Tests
When using spec notation, you can change a value for all tests within a `describe` group:
```ruby
class Config
def initialize
@version = 1
end
enddescribe Config do
subject do
Config.new
enddescribe 'original version' do
it "returns the original version" do
_(subject.instance_variable_get('@version')).must_equal 1
end
enddescribe 'sustituted version' do
substitute '@version', 2, on: Configit "returns the substituted version" do
_(subject.instance_variable_get('@version')).must_equal 2
end
end
end
```:warning: The target `on` is set explicitly in this case. If you omit this argument, `:subject` will be used as target by default which refers to the subject defined by the `subject {}` helper.
Alternatively, you can pass the substitution value as a block. This block will be evaluated once in the context of the test, in other words, you can use assignments done with `let` inside the block:
```ruby
class Config
def initialize
@version = 1
end
enddescribe Config do
subject do
Config.new
endlet :version do
2
enddescribe 'original version' do
it "returns the original version" do
_(subject.instance_variable_get('@version')).must_equal 1
end
enddescribe 'sustituted version' do
substitute '@version', on: Config do
version # set using "let" above
endit "returns the substituted version" do
_(subject.instance_variable_get('@version')).must_equal 2
end
end
end
```If both a substitution value and a substitution block are present, the latter takes precedence.
It's safe to use multiple `substitute` statements within one `describe` block.
(The spec integration is borrowed from [minitest-around](https://rubygems.org/gems/minitest-around) for elegance and compatibility.)
## Development
To install the development dependencies and then run the test suite:
```
bundle install
bundle exec rake # run tests once
bundle exec guard # run tests whenever files are modified
```You're welcome to [submit issues](https://github.com/svoop/minitest-substitute/issues) and contribute code by [forking the project and submitting pull requests](https://docs.github.com/en/get-started/quickstart/fork-a-repo).
## License
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).