问题
I try to run an update test with rspec for my rails application.
I'm using rspec 3.5 and rails 4.
The behaviour is supposed to be the following :
When i create a new service with a selling price, it's create a Price instance and set the relation with the service. Then, when i update my service, if there is no selling price, it's destroy the price record (requirement of the client to save space in database). The process i implemented seems to be working fine, when i test with the UI and i check the count of Price record, it's decrease by one like it's suppose. However, the unit test if failing.
Here is the code :
Service Controller :
def update
@service.assign_attributes(service_params)
puts "update method"
respond_to do |format|
if @service.valid?
if params['preview']
@service.build_previews
format.js { render 'services/preview' }
else
@service.save!
format.html { redirect_to client_trip_days_path(@client, @trip), notice: t('flash.services.update.notice') }
end
else
format.html { render :edit }
format.js { render :new }
end
end
end
The callback in the Service model :
def create_or_update_price
puts "in create or update price"
if selling_price.present? && price.present?
self.price.update_columns(:trip_id => trip.id, :currency => trip.client.currency, :purchase_price => purchase_price, :selling_price => selling_price)
elsif selling_price.present? && !price.present?
self.price = RegularPrice.create(:trip => trip, :currency => trip.client.currency, :purchase_price => purchase_price, :selling_price => selling_price)
elsif !selling_price.present? && price.present?
self.price.destroy
end
end
The test :
it "updates the lodging and destroy the price" do
puts "nombre de service avant création : "
puts Service.count
puts "nombre de prix avant création : "
puts Price.count
lodging = FactoryGirl.create(:lodging_service, selling_price: 200)
puts "nombre de service après création : "
puts Service.count
puts "nombre de prix après création : "
puts Price.count
expect(lodging.reload.price).to be_present
puts "nombre de prix avant update : "
puts Price.count
puts "id"
puts lodging.id
patch :update, client_id: client.id, trip_id: trip.id, id: lodging.to_param, service: valid_attributes_no_more_price
# patch :update, client_id: client.id, trip_id: trip.id, id: lodging.id, service: valid_attributes_with_price
puts "nombre de prix après update : "
puts Price.count
# expect{
# patch :update, client_id: client.id, trip_id: trip.id, id: lodging.id, service: valid_attributes_no_more_price
# }.to change(RegularPrice, :count).by(0)
expect(lodging.reload.price).to be_nil
end
let(:valid_attributes_no_more_price) {
attributes_for(:lodging_service, trip: trip, selling_price: "")
}
As you can see, there is a lot of puts since i try to find what is wrong.
The output is : nombre de service avant création : 0 nombre de prix avant création : 0 in create or update price nombre de service après création : 1 nombre de prix après création : 1 nombre de prix avant update : 1 id 10 nombre de prix après update : 1
Failure/Error: expect(lodging.reload.price).to be_nil
expected: nil
got: #<RegularPrice id: 2, label: nil, currency: "CHF", selling_price: 200.0, priceable_type: "Service", p...ated_at: "2017-07-13 08:08:47", quantity: 1, type: "RegularPrice", position: 1, purchase_price: nil>
As we can see, it's look like the callback is not fired after the update, and the action in the controller is not reached.
Have you any idea what is going wrong?
Thanks :)
PS: I always have trouble to include code in my questions, is there a tutorial on how to make it?
回答1:
Since you did not mentioned your ruby version I'll assume it's 2.
First of all you need to learn how to properly debug your code in order to fix the issues yourself.
Here is what you have to do:
1.Add pry
gem to your app, pry-byebug there is also a version for ruby 1.9.3.
2.Add a break point in your code
it "updates the lodging and destroy the price" do
(...) # Code here.
binding.pry # The debugger will open a console at this point
(...) # Maybe more code here
end
3.Verify all the variable and their values and see where the problem lies
In case you could not find the issue with binding.pry
in your rspec file before the expect add it to after the first line of the method, and you can step through the debugger by typing next
in the console opened by pry (it will be where your rails server is runnig).
If that still does not help, try and add a binding.pry
in your classes and see what is the state in there.
Spend a few minutes/hours now to learn debugging and it will save you days/weeks in long term. (while you are learning you don't really know how a program should behave and that extra knowledge is priceless, after a while you only need a debugger for extremely complicated issues).
来源:https://stackoverflow.com/questions/45074980/rspec-and-rails-4-update-skip-callback