テストメソッド

def self.runnable!
  return if !(Rails.env.staging? || Rails.env.production?) || ENV["IMPORTANT_CODE"].present?

  raise Error
end

アフター

describe "#runnable!" do
  subject { described_class.runnable! }

  let(:set_code) { ENV["IMPORTANT_CODE"] = "hoge" }
  let(:unset_code) { ENV["IMPORTANT_CODE"] = nil }

  context "development" do
    before { allow(Rails.env).to receive(:development?).and_return(true) }

    it_behaves_like "check important code for development"
  end

  context "staging" do
    before { allow(Rails.env).to receive(:staging?).and_return(true) }

    it_behaves_like "check important code for production"
  end
  ...
end
shared_examples "check important code for development" do
  context "important code の未設定の場合" do
    it { unset_code; expect(subject).to be_falsey }
  end
  context "important code の設定の場合" do
    it { set_code; expect(subject).to be_falsey }
  end
end

shared_examples "check important code for production" do
  context "important code の未設定の場合" do
    it { unset_code; expect{ subject }.to raise_error(Error) }
  end
  context "important code の設定の場合" do
    it { set_code; expect(subject).to be_falsey }
  end
end

何が変わったか?

チェックの方法をテンプレート化してそれを使用する。 呼び出し元ではどの環境で実行したのかを変更するのみで、メンテナスがし易い。

ビフォー

テスト概要

特定の環境変数に値が入っていないと例外をスローするメソッドのテスト。 環境によって(development、staging、productionだと、development)は発生を抑えたい。 staging、productionでは同様の処理を行いエラーを発生させたい。

describe "#runnable!" do
  subject { described_class.runnable! }

  let(:set_code) { ENV["IMPORTANT_CODE"] = "hoge" }
  let(:unset_code) { ENV["IMPORTANT_CODE"] = nil }

  context "development" do
    before { allow(Rails.env).to receive(:development?).and_return(true) }

    context "important code の未設定の場合" do
      it { unset_code; expect(subject).to be_falsey }
    end
    context "important code の設定の場合" do
      it { set_code; expect(subject).to be_falsey }
    end
  end
   
  context "staging" do
    before { allow(Rails.env).to receive(:development?).and_return(true) }

    context "service code の未設定の場合" do
      it { unset_code; expect{ subject }.to raise_error(Error) }
    end
  ...
end

懸念

環境毎にテストケースが増えてしまう。