RSpec"count"change.by?

RSpec "count" change.by?

所以我在看:https://rubyplus.com/articles/1491-Basic-TDD-in-Rails-Writing-Validation-Tests-for-the-Model

刚刚看到测试技术,我看到了这个:

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

特别是最后一行:end.to change{Article.count}.by(1)。来自阅读https://relishapp.com/rspec/rspec-expectations/v/3-7/docs/built-in-matchers/change-matcher

它具体说:

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:

这是有道理的。但是我们在代码块中测试 Article.count 实际上并不是 "doing" 任何东西(article.save 实际上改变了 Article.count 那么这到底是如何工作的呢?测试看看 运行 和 "prerun" 之前代码块中的内容...比较 .by(1) 之后?

谢谢

有两个代码块正在执行。代码块传递给 expect,代码块传递给 change。这就是伪代码中真正发生的事情。

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)

我会重构您的测试,使其更容易理解,如下所示:

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