Dylan Markow
2007-Oct-16 15:01 UTC
[rspec-users] Controller iterating through returned records and appending to each
I have a controller that gets a list of employees (which has an "include => [:salaries, :incentives, :billablegoals, :reviews]"). I then need it to iterate through each employee and determine their current active goal based on the "effective date." After playing around with it a bunch, I got the following to work. Only problem is that if I remove the "@employees.each { |e|....." line, the test still passes (which means the test isn''t accurate). I had to stub out "current_goal" and "current_goal=" because I kept getting "unexpected call" errors on each. Controller excerpt: def employee_report @employees = Employee.find_active_employees @employees.each { |e| e.current_goal = e.billablegoals.empty? ? "-" : e.billablegoals.select { |bg| bg.effective_date <= Date.today }[0].goal } end Spec: require File.dirname(__FILE__) + ''/../spec_helper.rb'' describe ManagementController, "GET /management/employee_report" do before(:each) do @bg1 = mock_model(Billablegoal, :effective_date => Date.today-3.months, :goal => 50) @bg2 = mock_model(Billablegoal, :effective_date => Date.today + 1.month, :goal => 75) @mock_employee = mock_model(Employee, :billablegoals => stub(Array, :select => [@bg1], :empty? => false)) @employees = [@mock_employee] @employees.each { |f| f.stub!(:current_goal=) } @employees.each { |f| f.stub!(:current_goal) } Employee.stub!(:find_active_employees).and_return(@employees) login # used to bypass the restful_authentication login_required filter end def do_get get :employee_report end it "should add the current billable goal to each returned employee" do do_get @employees[0].should respond_to(:current_goal) end end -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20071016/72adeac6/attachment.html
David Chelimsky
2007-Oct-16 15:24 UTC
[rspec-users] Controller iterating through returned records and appending to each
On 10/16/07, Dylan Markow <dmarkow at gmail.com> wrote:> I have a controller that gets a list of employees (which has an "include => > [:salaries, :incentives, :billablegoals, :reviews]"). I then need it to > iterate through each employee and determine their current active goal based > on the "effective date." > > After playing around with it a bunch, I got the following to work. Only > problem is that if I remove the "@employees.each { |e|....." line, the test > still passes (which means the test isn''t accurate). I had to stub out > "current_goal" and "current_goal=" because I kept getting "unexpected call" > errors on each. > > Controller excerpt: > def employee_report > @employees = Employee.find_active_employees > @employees.each { |e| e.current_goal = e.billablegoals.empty? ? "-" : > e.billablegoals.select { |bg| bg.effective_date <= Date.today }[0].goal } > end > > Spec: > > > require File.dirname(__FILE__) + ''/../spec_helper.rb'' > > describe ManagementController, "GET /management/employee_report" do > > > before(:each) do > @bg1 = mock_model(Billablegoal, :effective_date => Date.today-3.months, > :goal => 50) > @bg2 = mock_model(Billablegoal, :effective_date => Date.today + 1.month > , :goal => 75) > @mock_employee = mock_model(Employee, :billablegoals => stub(Array, > :select => [@bg1], :empty? => false)) > @employees = [@mock_employee] > @employees.each { |f| f.stub!(:current_goal=) } > @employees.each { |f| f.stub!(:current_goal) } > > Employee.stub!(:find_active_employees).and_return(@employees) > login # used to bypass the restful_authentication login_required filter > end > > def do_get > get :employee_report > end > > it "should add the current billable goal to each returned employee" do > do_get > @employees[0].should respond_to(:current_goal)What are you expecting to fail here? The only expectation that you are setting is that the first employee should respond_to(:current_goal). Since you''re stubbing that method, this is always going to pass no matter what happens in the controller. You could even comment out the do_get line in the example and it would still pass.
Dylan Markow
2007-Oct-16 15:24 UTC
[rspec-users] Controller iterating through returned records and appending to each
Okay I''m retarded. I added a helper method "def current_goal" to my Employee model and can test it there, so I don''t even need the @employees.each... line. Dylan Markow wrote:> > I have a controller that gets a list of employees (which has an "include > => > [:salaries, :incentives, :billablegoals, :reviews]"). I then need it to > iterate through each employee and determine their current active goal > based > on the "effective date." > > After playing around with it a bunch, I got the following to work. Only > problem is that if I remove the "@employees.each { |e|....." line, the > test > still passes (which means the test isn''t accurate). I had to stub out > "current_goal" and "current_goal=" because I kept getting "unexpected > call" > errors on each. > > Controller excerpt: > def employee_report > @employees = Employee.find_active_employees > @employees.each { |e| e.current_goal = e.billablegoals.empty? ? "-" : > e.billablegoals.select { |bg| bg.effective_date <= Date.today }[0].goal } > end > > Spec: > > require File.dirname(__FILE__) + ''/../spec_helper.rb'' > > describe ManagementController, "GET /management/employee_report" do > > before(:each) do > @bg1 = mock_model(Billablegoal, :effective_date => > Date.today-3.months, > :goal => 50) > @bg2 = mock_model(Billablegoal, :effective_date => Date.today + > 1.month, > :goal => 75) > @mock_employee = mock_model(Employee, :billablegoals => stub(Array, > :select => [@bg1], :empty? => false)) > @employees = [@mock_employee] > @employees.each { |f| f.stub!(:current_goal=) } > @employees.each { |f| f.stub!(:current_goal) } > Employee.stub!(:find_active_employees).and_return(@employees) > login # used to bypass the restful_authentication login_required > filter > end > > def do_get > get :employee_report > end > > it "should add the current billable goal to each returned employee" do > do_get > @employees[0].should respond_to(:current_goal) > end > > end > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >-- View this message in context: http://www.nabble.com/Controller-iterating-through-returned-records-and-appending-to-each-tf4634810.html#a13235703 Sent from the rspec-users mailing list archive at Nabble.com.
Pat Maddox
2007-Oct-16 16:12 UTC
[rspec-users] Controller iterating through returned records and appending to each
On 10/16/07, Dylan Markow <dmarkow at gmail.com> wrote:> I have a controller that gets a list of employees (which has an "include => > [:salaries, :incentives, :billablegoals, :reviews]"). I then need it to > iterate through each employee and determine their current active goal based > on the "effective date." > > After playing around with it a bunch, I got the following to work. Only > problem is that if I remove the "@employees.each { |e|....." line, the test > still passes (which means the test isn''t accurate). I had to stub out > "current_goal" and "current_goal=" because I kept getting "unexpected call" > errors on each. > > Controller excerpt: > def employee_report > @employees = Employee.find_active_employees > @employees.each { |e| e.current_goal = e.billablegoals.empty? ? "-" : > e.billablegoals.select { |bg| bg.effective_date <= Date.today }[0].goal } > end > > Spec: > > > require File.dirname(__FILE__) + ''/../spec_helper.rb'' > > describe ManagementController, "GET /management/employee_report" do > > > before(:each) do > @bg1 = mock_model(Billablegoal, :effective_date => Date.today-3.months, > :goal => 50) > @bg2 = mock_model(Billablegoal, :effective_date => Date.today + 1.month > , :goal => 75) > @mock_employee = mock_model(Employee, :billablegoals => stub(Array, > :select => [@bg1], :empty? => false)) > @employees = [@mock_employee] > @employees.each { |f| f.stub!(:current_goal=) } > @employees.each { |f| f.stub!(:current_goal) } > > Employee.stub!(:find_active_employees).and_return(@employees) > login # used to bypass the restful_authentication login_required filter > end > > def do_get > get :employee_report > end > > it "should add the current billable goal to each returned employee" do > do_get > @employees[0].should respond_to(:current_goal) > end > > end > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >I think you ought to push current_goal down into the model. class Employee < ActiveRecord::Base has_many :billablegoals def current_goal bill_goal = billablegoals.detect {|bg| bg.effective_date <= Date.today } return nil if bill_goal.blank? bill_goal.goal end # or do it all in the db def current_goal bill_goal = billablegoals.find :first, :conditions => ["effective_date <= ?", Date.today] return nil if bill_goal.blank? bill.goal end end Your controller spec becomes absurdly simple: describe ManagementController, "GET /management/employee_report" do before(:each) do Employee.stub!(:find_active_employees).and_return [:active1, :active2] end def do_get get :employee_report end it "should find the active employees" do Employee.should_receive(:find_active_employees).and_return [:active1, :active2] do_get end it "should assign the employees to the view" do do_get assigns[:employees].should == [:active1, :active2] end end And finally in your view you iterate through the employees, showing their goal: <% @employees.each do |e| %> Goal: <%= e.current_goal || "=" %> <% end %> Very nice. Pat