RSpec change匹配器工作原理疑问:Article.count检测机制
change Matcher Works with Rails Models Great question—this matcher is a total workhorse in Rails TDD, and your hunch about how it operates is spot-on! Let me walk you through exactly what happens step by step when you run that test code:
First, capture the initial value
RSpec runs the block insidechange{Article.count}first, grabbing the current number ofArticlerecords in the database and storing that number as the baseline value.Execute the action you're testing
Next, it runs the code inside theexpect { ... }block—so in your case, that's thearticle.savecall that creates or updates a record. This is the code you're verifying will cause a change.Capture the new value and compare
After the action runs, RSpec runs thechange{Article.count}block again to get the updated count. It then calculates the difference between the new value and the initial baseline.Check if the difference matches your expectation
Finally, it checks if that difference matches the value you specified with.by(1). If the count increased by exactly 1 (meaning yourarticle.savesuccessfully created a new record), the test passes. If the count stayed the same (save failed due to validations, for example) or changed by a different number, the test fails with a clear message about what went wrong.
A quick concrete example:
Suppose your database starts with 3 Article records.
- Initial count (from
change{Article.count}) is 3. - You run
article.save, which successfully creates a new record. - Updated count is 4.
- The difference is 1, so
expect { article.save }.to change{Article.count}.by(1)passes.
You can also use variations of this matcher for more specific checks:
expect { ... }.to change{Article.count}.from(3).to(4): Verifies the count goes exactly from 3 to 4expect { article.destroy }.to change{Article.count}.by(-1): Checks for a decrease of 1expect { ... }.to change{Article.count}: Just verifies the count changed at all, regardless of the number
内容的提问来源于stack exchange,提问作者msmith1114

