Back to Repositories

Testing Environment Variable Logging Implementation in dotenv

This test suite validates the logging functionality of the Dotenv::LogSubscriber class, ensuring proper logging behavior when environment variables are loaded, updated, saved and restored. It verifies the logging implementation for various environment variable operations and edge cases.

Test Coverage Overview

The test suite provides comprehensive coverage of the Dotenv::LogSubscriber functionality.

Key areas tested include:
  • Environment file loading and logging
  • Variable update logging with overwrite scenarios
  • Environment snapshot saving operations
  • Environment restoration logging including variable unset cases
Edge cases covered include unchanged variables, non-overwritten updates, and empty restore operations.

Implementation Analysis

The testing approach utilizes RSpec’s describe/context blocks for logical test organization and StringIO for log capture and verification.

Key patterns include:
  • Before block setup for logger configuration
  • Let blocks for test dependencies
  • Expectation matching against log output
  • Negative assertions for logging exclusions

Technical Details

Testing tools and configuration:
  • RSpec as the testing framework
  • ActiveSupport::Notifications for instrumentation
  • StringIO for log capture
  • Logger class for output handling
  • Environment variable manipulation
  • Fixture files for test data

Best Practices Demonstrated

The test suite demonstrates several testing best practices.

Notable implementations include:
  • Isolated test contexts
  • Consistent logging verification patterns
  • Proper test setup and teardown
  • Clear test descriptions
  • Comprehensive edge case coverage
  • Efficient test organization

bkeepers/dotenv

spec/dotenv/log_subscriber_spec.rb

            
require "spec_helper"
require "active_support/all"
require "rails"
require "dotenv/rails"

describe Dotenv::LogSubscriber do
  let(:logs) { StringIO.new }

  before do
    Dotenv.instrumenter = ActiveSupport::Notifications
    Dotenv::Rails.logger = Logger.new(logs)
  end

  describe "load" do
    it "logs when a file is loaded" do
      Dotenv.load(fixture_path("plain.env"))
      expect(logs.string).to match(/Loaded.*plain.env/)
      expect(logs.string).to match(/Set.*PLAIN/)
    end
  end

  context "update" do
    it "logs when a new instance variable is set" do
      Dotenv.update({"PLAIN" => "true"})
      expect(logs.string).to match(/Set.*PLAIN/)
    end

    it "logs when an instance variable is overwritten" do
      ENV["PLAIN"] = "nope"
      Dotenv.update({"PLAIN" => "true"}, overwrite: true)
      expect(logs.string).to match(/Set.*PLAIN/)
    end

    it "does not log when an instance variable is not overwritten" do
      ENV["FOO"] = "existing"
      Dotenv.update({"FOO" => "new"})
      expect(logs.string).not_to match(/FOO/)
    end

    it "does not log when an instance variable is unchanged" do
      ENV["PLAIN"] = "true"
      Dotenv.update({"PLAIN" => "true"}, overwrite: true)
      expect(logs.string).not_to match(/PLAIN/)
    end
  end

  context "save" do
    it "logs when a snapshot is saved" do
      Dotenv.save
      expect(logs.string).to match(/Saved/)
    end
  end

  context "restore" do
    it "logs restored keys" do
      previous_value = ENV["PWD"]
      ENV["PWD"] = "/tmp"
      Dotenv.restore

      expect(logs.string).to match(/Restored.*PWD/)

      # Does not log value
      expect(logs.string).not_to include(previous_value)
    end

    it "logs unset keys" do
      ENV["DOTENV_TEST"] = "LogSubscriber"
      Dotenv.restore
      expect(logs.string).to match(/Unset.*DOTENV_TEST/)
    end

    it "does not log if no keys unset or restored" do
      Dotenv.restore
      expect(logs.string).not_to match(/Restored|Unset/)
    end
  end
end