Back to Course

Practice · SOLID · DIP · Card 10

Why is the test flaky around midnight?

A method that reads Time.current directly. The CI test passes 99% of the time. The 1% is the bug.

The code

A class that decides whether a subscription is past its grace period.

class GracePeriodCheck
  GRACE_DAYS = 7

  def call(subscription)
    return false if subscription.canceled_at.nil?
    Time.current > subscription.canceled_at + GRACE_DAYS.days
  end
end

# The test:
test "in grace period at the start" do
  sub = subscriptions(:karim)
  sub.update!(canceled_at: 3.days.ago)
  assert_equal false, GracePeriodCheck.new.call(sub)
end

# Passes 99% of the time. Occasionally fails when CI runs near midnight.

The question

Why is the test flaky, and what's the DIP-shaped fix that makes it stop?

Take a moment. The test references "3 days ago" and the production code references "now." Both move forward in time, but the test\'s "now" is the test\'s instantiation, and the production code\'s "now" is when Time.current evaluates. They might not be the same instant.