expected #count to have changed by 1, but was not given a block
The #change
matcher expects a block in which some action is performed that effects the expected change. Try this:
expect { Account.create(account: acc) }.to change{ Account.count }.by(1)
See https://www.relishapp.com/rspec/rspec-expectations/v/2-0/docs/matchers/expect-change
Expected Count to change by 1 but was changed by 0 - Pry within Rspec
Issue is with the attributes_for and the association with FactoryBot. This made the test pass:
it 'should create existing customer' do
expect do
post :create, params: { existing_customer: FactoryBot.attributes_for(:existing_customer)
.merge(region_id: create(:region)) }
end.to change(ExistingCustomer, :count).by(1)
end
Rspec - expected #count to have changed by 1, but was changed by 0
I don't know enough about your setup to determine if it's an error in the upstream code or if it's simply a race condition. My gut tells me you're racing. Try adding a sleep after the click save
to see if that helps.
If your test is booting up a second process for your server (which I suspect it is) then your test is firing off a request (to be handled by the server at some future time) and then immediately checking the blog
count. The request hasn't been handled by your server by the time you're checking the blog count.
Instead of checking the blog count at the database level, I'd recommend checking text or elements on the page. The user is getting some feedback from the save right? Assert against that.
rspec to have changed by 1, but was changed by 2
Calling subject
within your expect
block evaluates the subject
block. Subject block calls your action, but it needs to evaluate custom_action
to do so. In the end, while evaluating the block, your custom_action
block creates one CustomAction
and your actual, controller action creates one more during the request.
Change your let
to let!
to fix your test.
(LikesController#create) expected #count to have changed by 1, but was changed by 0 ,Please teach me a hint
You've got an error in your code somewhere, most likely, which is why the Like
count fails to increment. First, I'd try and figure out why it isn't incrementing. Since you asked for a hint, here's one way you can split out the "success like function" block:
context "valid" do
before do
post :create, format: :js, params: { post_id: post1.id, id: like.id }
end
it "success" do
# You can inject a binding.pry here if needed
expect(response.status).to eq(200)
end
it "response" do
# You can inject a `binding.pry` here if needed
# You can also inspect the `response.body` with puts if needed
expect(JSON.parse(response.body)).to include(
# You would modify this to match the shape of your response
post: a_hash_including(
like: like.id
)
)
end
end
You'll want to install pry-rails
and pry-byebug
gems (for inspecting).
The reason behind splitting them up is it makes it easier to determine the issue (you can have a valid response code but not the expected result, for example). This comes with some caveats (it will make for slower tests) but in this example it will make it easier to determine why your post
is failing.
The snippet above should help you debug the error; once you fix it you can revert back to your previous method of checking.
expected result to have changed by 1, but was changed by 0
Here, you're showing your comments controller, expecting one of its actions to be hit. However, your test case is actually calling the create
route of the Subscriptions controller.
When, in your test case, you write describe SubscribersController do
, you are establishing a scope for the HTTP requests you make in that block.
So when you call post :create, subscriber: subscriber, comment: comment
,
it's the Subscriptions controller which is being hit.
In general, in order to debug, you should
- check that the area of code in question is being called
- check that values are correct (here, that would mean that the
Comment.create
object is successfully saved.
Rspec expect( ) vs expect { }
The expect(...)
syntax is used to expect that the return value of the statement in the parentheses matches a certain condition, like:
expect(result).to eq(3)
expect(list).not_to be_empty
expect(string).to match(/regexp/)
expect(1..10).to cover(3)
The expect { ... }
runs the block and doesn't really care about the return value of the block, but instead about the side-effects of running the code in the block. Like that another value changes by running the block or that an exception is raised.
expect { api_request }.to raise_error(NotFoundError)
expect { object.action }.to change(object, :value).from(old).to(new)
expect { actual }.to output("some output").to_stdout
Find more examples in the RSpec docs
In your example
expect { array << 1 }.to change { array.count }.by(1)
because a side-effect of pushing a value into an array is that the count of elements in the array changes. But
expect(array << 1).to change { arr.count }.by(1)
does not work, because the return value of expect(array << 1)
is [1, 2, 3, 1]
and this syntax does not support the change
matcher.
Related Topics
How to Add "Somewhere" a 'Before(:Each)' Hook So That All Spec File Can Run It
Ruby on Rails: How to Use Oauth2::Accesstoken.Post
What's the Best Background Job Management Library for Rails
How to Remove Xcode 4.2 and Install 4.1 to Develop Ruby/Rails on Osx Lion
How to Update to Ruby 2.1.2 Using Rails 3.2.3
Require': Cannot Load Such File -- Spec_Helper (Loaderror)
Use Windows or Linux to Start Work with Ruby on Rails
Passing Params to Cancan in Ror
Ruby Tcpsocket Write Doesn't Work, But Puts Does
How to Reference a Method in Another Ruby Code File
Access Ruby Hash Using Dotted Path Key String
How to Integrate 'Premailer' with Rails
Kill Process and Sub-Processes in Ruby on Windows
Running into Issues with Rvm During Ruby Install (1.9.2)
How to Populate an Array with Random Numbers
Calling a Sinatra App Instance Method from Testcase
How to Round a Float to a Specified Number of Significant Digits in Ruby