[RUBY] The story of initializing Money :: Currency when testing

I think there are many products that manage money using RubyMoney. RubyMoney provides a currency setting by default, but you can override that setting if you wish. In many systems, once you set the settings when building the app, you will not change the settings after that, but in the context of testing, you may want to initialize the settings once changed. Isn't there?

In this article, I will explain how to initialize the currency setting of RubyMoney in such a case.

As a premise, set the currency as follows.

cad = Money::Currency.find(:cad)

cad.name # => Canadian Dollar

Money::Currency.register(
  :priority            => cad.priority,
  :iso_code            => cad.iso_code,
  :name                => 'Something Different',
  :subunit             => cad.subunit,
  :subunit_to_unit     => cad.subunit_to_unit,
  :thousands_separator => cad.thousands_separator,
  :decimal_mark        => cad.decimal_mark
)

cad = Money::Currency.find(:cad)
cad.name # => Something Different

The Money :: Currency class manages currency settings with an instance variable called @ table. Therefore, it would be nice if this instance variable could be reset. However, due to the specifications, @ table cannot be accessed directly, so initialize it as follows.

 Money::Currency.instance_variable_set('@table', nil)
 Money::Currency.table # => reloading the initial setting

It's easy. However, even after performing the above initialization, I still receive the overwritten value.

cad = Money::Currency.find(:cad)
cad.name # => Something Different
Money::Currency.instance_variable_set('@table', nil)
Money::Currency.table
cad = Money::Currency.find(:cad)
cad.name # => Something Different.Not initialized!

Follow the library implementation in detail to find the answer. Once changed, the settings must be consistent after the application is launched, that is, from the start of the Ruby process to the end of that process. To implement that specification, Money :: Currency also manages the instance itself as a class variable. That way, as library users, we don't have to worry about the settings under development. With that in mind, the improved code is below.

cad.name # => Something Different
Money::Currency.class_variable_set('@@instances', {})
Money::Currency.instance_variable_set('@table', nil)
Money::Currency.table
cad = Money::Currency.find(:cad)
cad.name # => Canadian Dollar

It has been successfully initialized, and if you write this code in spec_helper etc., you can guarantee the test that does not depend on the setting override of Money :: Currency under test.

But it's a hassle to write this setting. In fact, the latest RubyMoney :: Money master provides an APIMoney :: Currency.reset!To do this initialization. This is the pull request for that change. If you want to use this feature, please install the latest master. We hope that the next updated version of RubyMoney :: Money will be released soon.

English version is here

Recommended Posts

The story of initializing Money :: Currency when testing
[Java version] The story of serialization
The story of @ViewScoped consuming memory
The story of encountering Spring custom annotation
What is testing? ・ About the importance of testing
The story of updating SonarQube's Docker Container
The story of RxJava suffering from NoSuchElementException
The story of AppClip support in Anyca
The story of writing Java in Emacs
A story confirming the implementation of the SendGrid Java library when mail delivery fails
The story of low-level string comparison in Java
The story of making ordinary Othello in Java
The story of learning Java in the first programming
The story of introducing Ajax communication to ruby
The story of raising Spring Boot 1.5 series to 2.1 series
The story of tuning android apps with libGDX
The story of adding the latest Node.js to DockerFile
When the hover of Eclipse is hard to see
The story of migrating from Paperclip to Active Storage
The story of making a reverse proxy with ProxyServlet
The story of an Illegal State Exception in Jetty.
When the month of the date is acquired, the January shift
[Java] When writing the source ... A memorandum of understanding ①
The story of making Dr. Oakid using LINE BOT
The story of making dto, dao-like with java, sqlite