Процедурное поколение используется в большой степени в demoscene для создания сложной графики в маленьком исполняемом файле. Will Wright даже сказал, что был вдохновлен demoscene при создании Споры. Это может быть Вашим лучшим местом для запуска.
Мне очень нравится библиотека 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"
Лично я предпочитаю делать часы вводимыми, например:
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))
Сделайте time-warp
time-warp - это библиотека, которая делает то, что вы хотите. Это дает вам метод, который требует времени и блока, и все, что происходит в блоке, использует фиктивное время.
pretend_now_is(2000,"jan",1,0) do
Time.now
end
В зависимости от того, с чем вы сравниваете Time.now
, иногда вы можете изменить свои приборы для достижения той же цели или протестировать ту же функцию. Например, у меня была ситуация, когда мне нужно было, чтобы одно событие произошло, если какое-то время было в будущем, и другое, если это было в прошлом. Что мне удалось сделать, так это включить в свои приборы какой-то встроенный рубин (erb):
future:
comparing_date: <%= Time.now + 10.years %>
...
past:
comparing_date: <%= Time.now - 10.years %>
...
Затем в ваших тестах вы выбираете, какой из них использовать для тестирования различных функций или действий, основанных на времени относительно Time. сейчас
.
Этот тип работает и допускает вложение:
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
Я использую RSpec и сделал следующее: Time.stub! (: Now) .and_return (2.days.ago) перед вызовом Time.now. Таким образом, я могу контролировать время, которое я использовал для этого конкретного тестового примера
Также см. этот вопрос , где я также поместил этот комментарий.
В зависимости от того, с чем вы сравниваете Time.now
, иногда вы Вы можете изменить свои приспособления для достижения той же цели или протестировать ту же функцию. Например, у меня была ситуация, когда мне нужно было, чтобы одно событие произошло, если какое-то время было в будущем, и другое, если это было в прошлом. Что мне удалось сделать, так это включить в свои приборы какой-то встроенный рубин (erb):
future:
comparing_date: <%= Time.now + 10.years %>
...
past:
comparing_date: <%= Time.now - 10.years %>
...
Затем в ваших тестах вы выбираете, какой из них использовать для тестирования различных функций или действий, основанных на времени относительно Time. сейчас
.
В моем тестовом файле есть только это:
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 перезаписывается, чтобы использовать все, что когда-либо время, когда вы хотите, чтобы это было.