In some of my unit tests, I find the need to set today to a different value than the actual today. For example, to test the model method "balance_of_today", which takes no argument, I want to have Date.today be a specific date for the purpose of testing. In other words, I want to do something like this: mock_today(Date.new(2008, 2, 1)) do ... test code... end My implementation for mock_today is: def mock_today(date) $_mock_test_date = date Date.class_eval do class <<self alias original_today today end def self.today $_mock_test_date end end yield Date.class_eval do class <<self alias today original_today end end end So my questions are: 1) Is it a good idea to mock Date.today? 2) Can my implementation of mock_today be improved? I''m particularly worried about of the use of global variable, and of class_eval, since I heard class_eval is becoming outdated as Ruby 1.9 is coming out. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Nov 19, 8:20 pm, Eric LIn <ericlin...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> In some of my unit tests, I find the need to set today to a different > value than the actual today. For example, to test the model method > "balance_of_today", which takes no argument, I want to have Date.today > be a specific date for the purpose of testing. In other words, I want > to do something like this: > > mock_today(Date.new(2008, 2, 1)) do > ... test code... > end > > My implementation for mock_today is: > > def mock_today(date) > $_mock_test_date = date > > Date.class_eval do > class <<self > alias original_today today > end > > def self.today > $_mock_test_date > end > end > > yield > > Date.class_eval do > class <<self > alias today original_today > end > end > end > > So my questions are: > > 1) Is it a good idea to mock Date.today? > > 2) Can my implementation of mock_today be improved? I''m particularly > worried about of the use of global variable, and of class_eval, since > I heard class_eval is becoming outdated as Ruby 1.9 is coming out.I occasionally "timetravel" by overriding Time.now (and Date.today calls Time.now eventually). It goes a little like this class Time cattr_accessor :frozen_now self.frozen_now = nil class << self def now_with_freeze if @@frozen_now @@frozen_now else now_without_freeze end end alias_method_chain :now, :freeze end end Then you freeze by doing Time.frozen_now = ... and unfreeze by setting it back to nil. You could easily refactor this to have a block like syntax. Fred --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Nov 19, 2008, at 3:37 PM, Frederick Cheung wrote:> On Nov 19, 8:20 pm, Eric LIn <ericlin...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: >> In some of my unit tests, I find the need to set today to a different >> value than the actual today. For example, to test the model method >> "balance_of_today", which takes no argument, I want to have >> Date.today >> be a specific date for the purpose of testing. In other words, I want >> to do something like this: >> >> mock_today(Date.new(2008, 2, 1)) do >> ... test code... >> end >> >> My implementation for mock_today is: >> >> def mock_today(date) >> $_mock_test_date = date >> >> Date.class_eval do >> class <<self >> alias original_today today >> end >> >> def self.today >> $_mock_test_date >> end >> end >> >> yield >> >> Date.class_eval do >> class <<self >> alias today original_today >> end >> end >> end >> >> So my questions are: >> >> 1) Is it a good idea to mock Date.today? >> >> 2) Can my implementation of mock_today be improved? I''m >> particularly >> worried about of the use of global variable, and of class_eval, since >> I heard class_eval is becoming outdated as Ruby 1.9 is coming out. > > I occasionally "timetravel" by overriding Time.now (and Date.today > calls Time.now eventually). > It goes a little like this > > class Time > cattr_accessor :frozen_now > self.frozen_now = nil > class << self > def now_with_freeze > if @@frozen_now > @@frozen_now > else > now_without_freeze > end > end > alias_method_chain :now, :freeze > end > end > > Then you freeze by doing Time.frozen_now = ... and unfreeze by setting > it back to nil. You could easily refactor this to have a block like > syntax. > > FredOr use flexmock: require ''rubygems'' gem :flexmock require ''flexmock/test_unit'' # then in your test stopped_clock = Date.new(2008, 2, 1) flexmock(Date).should_receive(:today).returns(stopped_clock) -Rob Rob Biedenharn http://agileconsultingllc.com Rob-xa9cJyRlE0mWcWVYNo9pwxS2lgjeYSpx@public.gmane.org --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Thanks, both of these are good suggestions. I will look into them. On Nov 19, 12:43 pm, Rob Biedenharn <R...-xa9cJyRlE0mWcWVYNo9pwxS2lgjeYSpx@public.gmane.org> wrote:> On Nov 19, 2008, at 3:37 PM, Frederick Cheung wrote: > > > > > On Nov 19, 8:20 pm, Eric LIn <ericlin...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > >> In some of my unit tests, I find the need to set today to a different > >> value than the actual today. For example, to test the model method > >> "balance_of_today", which takes no argument, I want to have > >> Date.today > >> be a specific date for the purpose of testing. In other words, I want > >> to do something like this: > > >> mock_today(Date.new(2008, 2, 1)) do > >> ... test code... > >> end > > >> My implementation for mock_today is: > > >> def mock_today(date) > >> $_mock_test_date = date > > >> Date.class_eval do > >> class <<self > >> alias original_today today > >> end > > >> def self.today > >> $_mock_test_date > >> end > >> end > > >> yield > > >> Date.class_eval do > >> class <<self > >> alias today original_today > >> end > >> end > >> end > > >> So my questions are: > > >> 1) Is it a good idea to mock Date.today? > > >> 2) Can my implementation of mock_today be improved? I''m > >> particularly > >> worried about of the use of global variable, and of class_eval, since > >> I heard class_eval is becoming outdated as Ruby 1.9 is coming out. > > > I occasionally "timetravel" by overriding Time.now (and Date.today > > calls Time.now eventually). > > It goes a little like this > > > class Time > > cattr_accessor :frozen_now > > self.frozen_now = nil > > class << self > > def now_with_freeze > > if @@frozen_now > > @@frozen_now > > else > > now_without_freeze > > end > > end > > alias_method_chain :now, :freeze > > end > > end > > > Then you freeze by doing Time.frozen_now = ... and unfreeze by setting > > it back to nil. You could easily refactor this to have a block like > > syntax. > > > Fred > > Or use flexmock: > > require ''rubygems'' > gem :flexmock > require ''flexmock/test_unit'' > > # then in your test > > stopped_clock = Date.new(2008, 2, 1) > flexmock(Date).should_receive(:today).returns(stopped_clock) > > -Rob > > Rob Biedenharn http://agileconsultingllc.com > R...-xa9cJyRlE0mWcWVYNo9pwxS2lgjeYSpx@public.gmane.org--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk+unsubscribe@googlegroups.com For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---