Как фальсифицировать Time.now?

Процедурное поколение используется в большой степени в demoscene для создания сложной графики в маленьком исполняемом файле. Will Wright даже сказал, что был вдохновлен demoscene при создании Споры. Это может быть Вашим лучшим местом для запуска.

http://en.wikipedia.org/wiki/Demoscene

70
задан toro2k 8 March 2014 в 11:00
поделиться

8 ответов

Мне очень нравится библиотека Timecop . Вы можете делать временные деформации в блочной форме (точно так же, как временная деформация):

Timecop.travel(6.days.ago) do
  @model = TimeSensitiveMode.new
end
assert @model.times_up!

(Да, вы можете вкладывать блочные путешествия во времени.)

Вы также можете делать декларативные путешествия во времени:

class MyTest < Test::Unit::TestCase
  def setup
    Timecop.travel(...)
  end
  def teardown
    Timecop.return
  end
end

У меня есть некоторые огурцы помощники для Timecop здесь . Они позволяют вам делать такие вещи, как:

Given it is currently January 24, 2008
And I go to the new post page
And I fill in "title" with "An old post"
And I fill in "body" with "..."
And I press "Submit"
And we jump in our Delorean and return to the present
When I go to the home page
I should not see "An old post"
75
ответ дан 24 November 2019 в 13:20
поделиться

Лично я предпочитаю делать часы вводимыми, например:

def hello(clock=Time)
  puts "the time is now: #{clock.now}"
end

Или:

class MyClass
  attr_writer :clock

  def initialize
    @clock = Time
  end

  def hello
    puts "the time is now: #{@clock.now}"
  end
end

Однако многие предпочитают использовать имитацию / заглушку библиотеки. В RSpec / flexmock вы можете использовать:

Time.stub!(:now).and_return(Time.mktime(1970,1,1))

Или в Mocha:

Time.stubs(:now).returns(Time.mktime(1970,1,1))
43
ответ дан 24 November 2019 в 13:20
поделиться

Сделайте time-warp

time-warp - это библиотека, которая делает то, что вы хотите. Это дает вам метод, который требует времени и блока, и все, что происходит в блоке, использует фиктивное время.

pretend_now_is(2000,"jan",1,0) do
  Time.now
end
10
ответ дан 24 November 2019 в 13:20
поделиться

В зависимости от того, с чем вы сравниваете Time.now , иногда вы можете изменить свои приборы для достижения той же цели или протестировать ту же функцию. Например, у меня была ситуация, когда мне нужно было, чтобы одно событие произошло, если какое-то время было в будущем, и другое, если это было в прошлом. Что мне удалось сделать, так это включить в свои приборы какой-то встроенный рубин (erb):

future:
    comparing_date: <%= Time.now + 10.years %>
    ...

past:
    comparing_date: <%= Time.now - 10.years %>
    ...

Затем в ваших тестах вы выбираете, какой из них использовать для тестирования различных функций или действий, основанных на времени относительно Time. сейчас .

0
ответ дан 24 November 2019 в 13:20
поделиться

Этот тип работает и допускает вложение:

class Time
  class << self
    attr_accessor :stack, :depth
  end

  def self.warp(time)

    Time.stack ||= [] 
    Time.depth ||= -1 
    Time.depth += 1
    Time.stack.push time

    if Time.depth == 0 
      class << self    
          alias_method :real_now, :now  
          alias_method :real_new, :new

          define_method :now do
            stack[depth] 
          end

          define_method :new do 
            now 
          end
      end 
    end 

    yield

    Time.depth -= 1
    Time.stack.pop 

    class << self 
      if Time.depth < 0 
        alias_method :new, :real_new
        alias_method :now, :real_now
        remove_method :real_new
        remove_method :real_now 
      end
    end

  end
end

Его можно немного улучшить, отменив определение стека и методов доступа глубины в конце

Использование:

time1 = 2.days.ago
time2 = 5.months.ago
Time.warp(time1) do 

  Time.real_now.should_not == Time.now

  Time.now.should == time1 
  Time.warp(time2) do 
    Time.now.should == time2
  end 
  Time.now.should == time1
end

Time.now.should_not == time1 
Time.now.should_not be_nil
0
ответ дан 24 November 2019 в 13:20
поделиться

Я использую RSpec и сделал следующее: Time.stub! (: Now) .and_return (2.days.ago) перед вызовом Time.now. Таким образом, я могу контролировать время, которое я использовал для этого конкретного тестового примера

14
ответ дан 24 November 2019 в 13:20
поделиться

Также см. этот вопрос , где я также поместил этот комментарий.

В зависимости от того, с чем вы сравниваете Time.now , иногда вы Вы можете изменить свои приспособления для достижения той же цели или протестировать ту же функцию. Например, у меня была ситуация, когда мне нужно было, чтобы одно событие произошло, если какое-то время было в будущем, и другое, если это было в прошлом. Что мне удалось сделать, так это включить в свои приборы какой-то встроенный рубин (erb):

future:
    comparing_date: <%= Time.now + 10.years %>
    ...

past:
    comparing_date: <%= Time.now - 10.years %>
    ...

Затем в ваших тестах вы выбираете, какой из них использовать для тестирования различных функций или действий, основанных на времени относительно Time. сейчас .

1
ответ дан 24 November 2019 в 13:20
поделиться

В моем тестовом файле есть только это:

   def time_right_now
      current_time = Time.parse("07/09/10 14:20")
      current_time = convert_time_to_utc(current_date)
      return current_time
    end

, а в моем файле Time_helper.rb есть

  def time_right_now
    current_time= Time.new
    return current_time
  end

, поэтому при тестировании time_right_now перезаписывается, чтобы использовать все, что когда-либо время, когда вы хотите, чтобы это было.

0
ответ дан 24 November 2019 в 13:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: