Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

DateTime Problem in Rails Unit Tests

I'm working on unit tests for my Rails app and have run into the following problem.

I have an Event model with a fixture that boils down to:

concert:
  name:        Wallflowers
  start_at:    <%= DateTime.new(1999) %>

In my unit test, I have the following assertion:

assert_equal DateTime.new(1999), events(:concert).start_at

The test fails, with the following message:

<Fri, 01 Jan 1999 00:00:00 +0000> expected but was
<Thu, 31 Dec 1998 19:00:00 UTC +00:00>.

I can't figure out why its getting adjusted. The offset of the incorrect time is 5 hours, which is my local offset.

Other info that might be relevant:

  • The problem only occurs while testing--I don't have any problems in development
  • environment.rb contains config.time_zone = 'UTC'
  • The test works if I use Date.new instead of DateTime.new, but I need to use DateTime

What am I missing? Appreciate the help.

like image 713
Matt Mazur Avatar asked Dec 21 '09 02:12

Matt Mazur


2 Answers

Change it to this

concert:
  name: Wallflowers
  start_at: <%= DateTime.new(1999).to_s(:db) %>
like image 82
frogstarr78 Avatar answered Nov 05 '22 20:11

frogstarr78


ActiveRecord automatically converts all inserted timestamps to UTC. This explains why your concert time is adjusted to a different timezone. The first step would be to see if the problem is solved by you setting your config.time_zone in environment.rb to your timezone.

If that doesn't solve the issue, read on:

After some testing, I discovered that there seems to be some discrepancy with using DateTime in fixtures compared to the same code in a controller. If I used DateTime.new(1999) in my controller, the inserted column was 1999-01-01 00:00:00. If I used the same call in my fixture, the inserted column was 1999-01-01 10:30:00, which is my timezone. This was regardless of what config.time_zone was set to.

In both cases, changing the timezone correctly changed the ActiveRecord object fetched from the database.

In truth, I don't know which is the correct representation. I do know that the test passed when I changed the fixture to '1999-01-01 00:00' instead of using DateTime.new(1999). If the solution in the first paragraph doesn't work for you, try changing the fixture to the string representation of the date.

like image 41
vonconrad Avatar answered Nov 05 '22 20:11

vonconrad