LoginSignup
1
0

More than 3 years have passed since last update.

消費税改正に備える(テスト)

Posted at

はじめに

消費税改正に備えるっていったって、お金のことなんだからテスト欲しいよねって思って、テストのほうも準備しました。

テストのソースは長くなりがちなので、こちらを見てみてください。

方針

テストはモジュールのほうでガッチリやって、モジュールをextendしたクラスのほうはメソッドが使えることくらいを確認するくらいにします。

モジュールのテスト

モジュールのテストで、ちょっとおもしろそうなところだけ、ピックアップします。

テストごとにちゃんと作り直されるクラス

クラス定義をletで変数のようにしてるところはちょっとおもしろいと思っています。RubyはクラスもClassクラスのオブジェクトなので、こんな書き方ができて、これだとテストごとに毎回定義されるので、いろいろとテストがやりやすくなったなあと思っています。

let(:klass) do
  Class.new do
    extend WithTax

    attr_accessor :name, :price
    attr_with_tax :price

    def initialize(name, price)
      @price = price
    end
  end
end

実行日の固定化

実行したときによって結果が変わるテストは、実行日を止めておいたほうがよいと思っています。
たまにmasterのCIが落ちてワタワタしますが、実行日を決めておかなかったことが原因だったことが一度や二度ではなかったです。
あと、戻し忘れてほかのテストが落ちたり落ちなかったりするようになることも多かったので、止めたらすぐに戻すコードを書く癖をつけています。

なお、ここではTimecopを使っていますが、railsを使っている場合であれば、travel_toなどがあるので、そちらがいいと思います。

before { Timecop.freeze(Date.parse(execution_date)) }
after { Timecop.return }

.attr_with_taxがちゃんとメソッドを足せた?

respond_toマッチャーで、attr_with_taxを指定しているpriceにはprice_with_taxが設定されていること、指定していないnameにはname_with_taxが存在しないことを確認しています。

describe 'メソッドの追加' do
  let(:sample_item) { klass.new('Sample Item', 123) }

  it '#price_with_taxが存在すること' do
    expect(sample_item).to respond_to(:price_with_tax).with(1).argument
  end

  it '#name_with_taxが存在しないこと' do
    expect(sample_item).not_to respond_to(:name_with_tax)
  end
end

追加したメソッドはちゃんと動いてる?

足されることは確認できたので、今度は足されているメソッドが期待通り動くのか確認します。
このあたりは、ごく普通のテストみたいに書けました。

小数点以下の処理

小数点以下を切り捨てる仕様にしたので、小数点以下が0.5未満の例と0.5以上の例を挙げて確認しました。

describe '小数点以下の処理' do
  subject { sample_item.price_with_tax }

  let(:sample_item) { klass.new('Sample Item', price) }
  context 'price = 123のとき' do
    let(:price) { 123 }

    it '135.3->135(切り捨て)になること' do
      is_expected.to eq 135
    end
  end

  context 'price = 345のとき' do
    let(:price) { 345 }

    it '379.8->379(切り捨て)になること' do
      is_expected.to eq 379
    end
  end
end

税率

税率は実行日や指定日によって変わります。
2019/10/01の改正で10%になったので、その前日は8%で計算されていることなど、改正日の前後をピックアップして値のテストを行いました。

中身は長いのでこちらでみてください。

モジュールを利用しているクラスのテスト

モジュールのほうでがっちりテストしているので、ここでのテストは#price_with_taxが存在することを確認するのみとしました。

RSpec.describe SampleItem do
  describe '#price_with_tax' do
    subject { SampleItem.new('Sample Item', 123) }

    it '#price_with_taxが利用できること' do
      is_expected.to respond_to(:price_with_tax).with(1).argument
    end
  end
end

最後に

先にも書きましたが、「クラスはClassクラスのオブジェクト」が好きで、こういうのを書くとRubyっていいなって実感します。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0