简体   繁体   中英

Change Time.now timezone rails minitest

I've been trying to make a test work regardless of the server's timezone. There is a function that was called in the module I'm creating the test for which is:

Time.now().iso8601.to_s

I am able to stub the date and time properly however, I am currently on a GMT+8 timezone which makes the result of the above function:

2021-07-19T01:00:00+08:00

But upon deploying it in azure server, it becomes

2021-07-19T01:00:00-05:00

How can I get this test passing regardless of the server's timezone?

you could stub method :iso8601 to return a fake time for all instance of Time , then in all of your expectations which relative to the time, you should expect to equal the fake_time .

minitest

require "test_helper"
require "minitest/mock"
class StubTest < ActiveSupport::TestCase
  def freeze_time(fixed_time=Time.now, &block)
    Time.stub(:now,fixed_time) do
      fixed_time.stub(:iso8601, fixed_time) do
        block.call
      end  
    end
  end

  test "stub time" do
   freeze_time(stub_time=Time.new(2021)) do
     assert_equal Time.now.iso8601, stub_time
     task = # create task
     assert_equal task.deadline_at, stub_time
   end
  end
end

better approach (in my opinion), you'll run test code in a fixed time-zone block, reference: https://github.com/rails/rails/blob/main/activesupport/test/time_zone_test_helpers.rb

class StubTest < ActiveSupport::TestCase
  def with_env_tz(new_tz = "US/Eastern")
    old_tz, ENV["TZ"] = ENV["TZ"], new_tz
    yield
  ensure
    old_tz ? ENV["TZ"] = old_tz : ENV.delete("TZ")
  end

  test "stub time zone" do
    # support your code run on server in time-zone US/Eastern
    # Time.zone == 'US/Eastern' 
    out = Time.zone.now.iso8601

    # now you force in time-zone Europe/Athens
    with_env_tz "Europe/Athens" do
      assert_equal Time.now.iso8601, out # FAILED
    end
  end
end

so you could wrap all your test codes relative to time-zone inside a block run in fixed time-zone.

Time.now gives the time in System timezone. That is the system current timezone which is different for the server and your device.

What you want to use is Time.zone.now or Time.current which will return the time in Application timezone.

Time.current.iso8601.to_s

You can also set the the application timezone in config/application.rb which is UTC by default.

config.time_zone = "UTC"

Run Time.zone.name in rails console to find out the current application timezone.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM