Mocking/Stubbing ActiveRecord.config.default_timezone


#1

In tracking down a bug in AuthLogic I realized that I had made the same
error in one of my libraries. Knowing what the error was made creating
a test to expose it (using cucumber) rather trivial. However, it has
occurred to me that this sort of issue is far more subtle than I first
appreciated. So, I am looking for some opinions on how to test for this
sort of thing in a more general sense.

At issue is the setting of config values in environment.rb files and
their influence on user code. In the specific case I encountered this
code demonstrates the essence of the situation:

def active_row?
  time_now = DateTime.now
  return true if  (effective_from <= time_now and
                  (not superseded_after or superseded_after >=

time_now ))
return false
end

The error is that the time_now assignment is not testing whether or not
the default AR time is utc. The correct code is:

def active_row?
  if self.class.default_timezone == :utc
    time_now = DateTime.now.utc
  else
    time_now = DateTime.now
  end
  return true if  (effective_from <= time_now and
                  (not superseded_after or superseded_after >=

time_now ))
return false
end

My question is: How does one vary the config.default_timezone, or any
configuration value for that matter, in a cucumber step definition or
RSpec test?


#2

On Mon, Jan 26, 2009 at 7:23 AM, James B. removed_email_address@domain.invalid
wrote:

return true if (effective_from <= time_now and
(not superseded_after or superseded_after >= time_now
))
return false

This has nothing to do with your question - just a style suggestion:

effective_from <= time_now and (superseded_after.nil? or
superseded_after

= time_now)

No need to use ‘return’. And you don’t want to check if superseded_after
is
false - just nil (if it’s false, there’s a bug that would be hidden by
‘not
superseded’).

Carry on. :slight_smile:

///ark


#3

Mark W. wrote:

On Mon, Jan 26, 2009 at 7:23 AM, James B. removed_email_address@domain.invalid
wrote:

This has nothing to do with your question - just a style suggestion:

effective_from <= time_now and (superseded_after.nil? or
superseded_after = time_now)

No need to use ‘return’. And you don’t want to check if superseded_after
is false - just nil (if it’s false, there’s a bug that would be hidden by
‘not superseded’).

I prefer the style of explicit returns. It makes intent unambiguous.
Your point wrt nil? is well taken and I have modified the code to use
this idiom.


#4

Mark W. wrote:

The thing is that the Ruby idiom is to avoid unnecessary returns.
Because of this, using them actually makes code harder to read,
because you have to read it more carefully to see if they’re being
used for a legitimate reason.

If the method is short, the code simply falls through, and I am not
doing anything particularly subtle with the result, then I follow the
convention of no explicit return. If a method requires at least one
explicit return then I code all possible outcomes as returns. In such a
case, one should be reading the code more carefully, particularly if
one is writing it.

But, we digress. I am still looking for suggestions on recommended
approaches to testing application code that is dependent upon
environment.rb config values.


#5

On Mon, Jan 26, 2009 at 9:06 AM, James B. removed_email_address@domain.invalid
wrote:

I prefer the style of explicit returns. It makes intent unambiguous.

The thing is that the Ruby idiom is to avoid unnecessary returns.
Because of
this, using them actually makes code harder to read, because you have to
read it more carefully to see if they’re being used for a legitimate
reason.

Just one opinion.

///ark