Reputation: 113
I'm working on a foosball logging application.
My models follow the scheme: Game -> Team -> Position -> Goal
In Goal I have an after_save that will check if either team has scored 10 goals. If a team has, then it sets a winner(Team) and sets the Game.completed_at.
This functionality seems to save the winner and Game.completed_at in practice through user testing, but in my Rspec tests after a team reaches 10 goals I see the after_save callback being called in Goal, but after the callback in the test its as if none of those columns were saved. I'm not exactly sure what is going on.
class Goal < ActiveRecord::Base
after_save :complete_game
def complete_game
game = self.position.team.game
isGameComplete = false
game.teams.each do |team|
if team.get_goals_total == 10
team.winner = true
team.save!
puts "complete_game: team.winner: #{team.winner}"
game.completed_at = DateTime.now
game.save!
isGameComplete = true
end
end
puts "complete_game: game.completed_at: #{game.completed_at}"
end
Rspec Test:
it "sets a winner after ten goals" do
@blue_team.positions.first.goals.create
@blue_team.positions.first.goals.create
@blue_team.positions.first.goals.create
@blue_team.positions.first.goals.create
@blue_team.positions.first.goals.create
@blue_team.positions.first.goals.create
@blue_team.positions.first.goals.create
@blue_team.positions.first.goals.create
@blue_team.positions.first.goals.create
@blue_team.positions.first.goals.create
puts "winner: #{@blue_team.winner}"
puts "completed_at: '#{@game.completed_at}'"
expect(@blue_team.winner).to be true
end
Rspec Output:
complete_game: game.completed_at:
complete_game: game.completed_at:
complete_game: game.completed_at:
complete_game: game.completed_at:
complete_game: game.completed_at:
complete_game: game.completed_at:
complete_game: game.completed_at:
complete_game: game.completed_at:
complete_game: game.completed_at:
complete_game: team.winner: true
complete_game: game.completed_at: 02/20/2015 12:44 PM
TEST OUTPUT: winner: false
TEST OUTPUT: completed_at: ''
sets a winner after ten goals (FAILED - 1)
Looking at the logs the after_save sets the winner/completed_at, but outside of the callback in 'TEST OUTPUT' then winner/completed_at are not set.
Do callbacks in rspec tests not persist changes made in after_save callbacks? Works in production, doesn't seem to save changes in testing.
Upvotes: 0
Views: 1435
Reputation: 113
Received the following answer asking the question on reddit.com/r/rails (http://www.reddit.com/r/rails/comments/2wlhrf/how_to_testing_before_save_callbacks/)
After the callback was performed on the Team model, a .reload of the corresponding object was required.
Test passed as expected.
it "sets a winner after ten goals" do
10.times do
@blue_team.positions.first.goals.create
end
expect(@blue_team.reload.winner).to be true
end
Upvotes: 2
Reputation: 7405
You need to stub
callback actions :
@blue_team.stub(:complete_game).and_return(true)
Upvotes: 0