Q:

In rspec-rails the difference between "let" VS "let!"

I have googled this question but still not clear. I get that (:let) is lazily evaluated and will never be instantiated if you don't call it, while (:let!) is forcefully evaluated before each method call.
let(:article) = { Article.new(name: 'article1') }
let!(:article) = { Article.new(name: 'article1') }

Can any body explain it more and what are the benefits of using let!  

A:

Sometimes you want the indirect results of the let to be present.
For example...
let(:article) = { Article.create(name: 'article1' }

it "does not add an article with a duplicate name" do
  expect(Article.create(name: article.name)).not_to change(Article.count)
end

This would actually fail, because the Article.count before the test will not include the article object because it's not yet created, not until it's referenced.  So even though the new article (the one with the duplicate name) is not created, the test will still detect a change to Article.count
Now, if you do...
let!(:article) = { Article.create(name: 'article1' }

it "does not add an article with a duplicate name" do
  expect(Article.create(name: article.name)).not_to change(Article.count)
end

The article object will already exist in the Article.count before the expect and the test will pass.

