So I was looking at: https://rubyplus.com/articles/1491-Basic-TDD-in-Rails-Writing-Validation-Tests-for-the-Model
Just seeing techniques of testing and I saw this:
require 'rails_helper'
describe Article, type: :model do
  it 'is valid if title and description fields have value' do
    expect do
      article = Article.new(title: 'test', description: 'test')
      article.save
    end.to change{Article.count}.by(1)
  end
end
Specifically the last line: end.to change{Article.count}.by(1). From reading https://relishapp.com/rspec/rspec-expectations/v/3-7/docs/built-in-matchers/change-matcher
It says specifically:
The change matcher is used to specify that a block of code changes some mutable state. You can specify what will change using either of two forms:
Which makes sense. But were testing Article.count in the block of code which isn't actually "doing" anything (The article.save is what actually changed the Article.count so how exactly does this work? Does the test take a a look at whats in the block of code before it's ran and "prerun" it...the compare the .by(1) after?
Thanks
There are two blocks of code being executed. The block of code passed to expect, and the block of code passed to change. This is what's really happening, in pseudo-code.
difference = 1
initial_count = Article.count
article = Article.new(title: 'test', description: 'test')
article.save
final_count = Article.count
expect(final_count - initial_count).to eq(difference)
I would refactor your test to be a little easier to follow as this:
require 'rails_helper'
describe Article, type: :model do
  let(:create_article) { Article.create(title: 'test', description: 'test') }
  it 'is valid if title and description fields have value' do
    expect { create_article }.to change { Article.count }.by(1)
  end
end
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With