[RUBY] [Rails] RSpec error expected `User.count` to have changed by 1, but was not given a block

Introduction

I tried using Rails' test tool Rspec. During use, I was addicted to the error expected `User.count` to have changed by 1, but was not given a block, so I will leave it as a memorandum.

Problem source code

Here is the source code that gives the error.
Error source
      expect(
        find('input[name="commit"]').click 
      ).to change{User.count}.by(1)
Error details
Error expected `User.count` to have changed by 1, but was not given a block Translation `User.count` was expected to change by 1, but no block was given

When using the change matcher, I had to block expect. In other words, if it is (), the argument is passed, so it seems that you can pass the operation itself as {}. With that in mind, rewrite the source.

working source
      expect{
        find('input[name="commit"]').click 
      }.to change{User.count}.by(1)

When I ran it, it worked fine.

There is also a way to write the block as the method name do / end, so I rewrote the source like this and executed it.

Experiment 1
      expect do
        find('input[name="commit"]').click 
      end.to change{User.count}.by(1) 
Experiment 1 result success! !!

    27:       # }.to change{User.count}.by(1)
    28:       #Experiment
    29:       # expect(
    30:       #   find('input[name="commit"]').click 
    31:       # ).to change{User.count}.by(1)
 => 32:       binding.pry
    33:       expect do
    34:         find('input[name="commit"]').click 
    35:       end.to change{User.count}.by(1) 
    36: 
    37: 

[1] pry(#<RSpec::ExampleGroups::Nested::Nested>)> exit
If you enter the correct information, you can register as a new user and move to the top page.
When new user registration is not possible
If the information is incorrect, the user cannot be newly registered and will return to the new registration page.

Finished in 17.61 seconds (files took 1.73 seconds to load)
2 examples, 0 failures

I confirmed that it works normally even with the method name do / end.

By the way, I checked one more thing. Changed the block of chage to do / end.

Experiment 2
      expect do
        find('input[name="commit"]').click 
      end.to change do User.count end.by(1) 
Experiment 2 result failed. .. ..
     Failure/Error:
       expect do
         find('input[name="commit"]').click 
       end.to change do User.count end.by(1) 
     
     SyntaxError:
       Block not received by the `change` matcher. Perhaps you want to use `{ ... }` instead of do/end?

I got a syntax error.

Error details

Error Block not received by the change matcher. Perhaps you want to use{...}instead of do/end? Translation change Matcher has not received the block. Perhaps you want to use {...} instead of do / end?

The result was told to use {}. It seems good to unify with {} without using do / end.

Summary

Thank you for reading to the end.

Recommended Posts

[Rails] RSpec error expected `User.count` to have changed by 1, but was not given a block
I was charged a lot by AWS during development on rails, but ...