Rails 5 - Rspec期望更改计数不起作用

时间:2016-09-14 21:02:11

标签: ruby-on-rails ruby rspec rspec-rails

这可能是非常简单的事情,但我不能让Rspec期望更改计数来检测何时通过控制器的create方法创建新记录。

这是我的测试:

it "saves the new Post in the database" do
  expect{
    process :create, method: :post, params: { post: attributes_for(:post) }
  }.to change{Post.count}.by(1)  
end

它只是错误:

expected result to have changed by 1, but was changed by 0

查看test.log,在创建帖子时似乎没有显示任何错误:

  [1m[35m (0.0ms)[0m  [1m[36mbegin transaction[0m
  [1m[35m (0.1ms)[0m  [1m[34mSELECT COUNT(*) FROM "posts"[0m
  Processing by PostsController#create as HTML
  Parameters: {"post"=>{"content"=>"Quas adipisci illum repellat sapiente eos. Quae temporibus facilis. Corporis odit eaque reiciendis eum tempora. Nam dolor sint pariatur.", "excerpt"=>"Dicta veritatis voluptate at. Sed voluptatem corrupti sed impedit quae consequatur. Velit voluptates nisi est nihil. Explicabo qui animi expedita rerum.", "image_url"=>"https://hd.unsplash.com/photo-1413781892741-08a142b23dfe", "keywords"=>"blog, post, key, words", "post_type"=>"article", "published"=>"false", "title"=>"Pariatur laborum ut nostrum quis rem sunt libero."}}
  [1m[35m (0.0ms)[0m  [1m[35mSAVEPOINT active_record_1[0m
  [1m[36mPost Exists (0.1ms)[0m  [1m[34mSELECT  1 AS one FROM "posts" WHERE "posts"."title" = ? LIMIT ?[0m  [["title", "Pariatur laborum ut nostrum quis rem sunt libero."], ["LIMIT", 1]]
  [1m[35m (0.0ms)[0m  [1m[31mROLLBACK TO SAVEPOINT active_record_1[0m
  Rendering /home/nitrous/code/blog/app/views/posts/index.html.haml within layouts/application
  Rendered /home/nitrous/code/blog/app/views/posts/index.html.haml within layouts/application (0.0ms)
  Completed 200 OK in 9ms (Views: 0.6ms | ActiveRecord: 0.2ms)
  [1m[35m (0.1ms)[0m  [1m[34mSELECT COUNT(*) FROM "posts"[0m
  [1m[35m (0.1ms)[0m  [1m[31mrollback transaction[0m

帖子模型验证标题是唯一的。

我可以看到日志显示“Post Preists”,但如果确实如此,这就是它不保存新帖子的原因。那是为什么?

3 个答案:

答案 0 :(得分:0)

您的帖子更改不会在此更改。测试日志中的相关行:

[1m[35m (0.0ms)[0m  [1m[31mROLLBACK TO SAVEPOINT active_record_1[0m

“ROLLBACK”关键字表示您的帖子未通过验证且未创建。

答案 1 :(得分:0)

您很可能要么不在规范开头删除旧帖子,要么不使用随机数据创建新帖子,这会触发您的唯一​​性验证。

在规范设置期间清除数据库

手动

before { Post.destroy_all }

自动使用数据库清理程序:

使用https://github.com/DatabaseCleaner/database_cleaner

RSpec.configure do |config|
  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)
  end

  config.around(:each) do |example|
    DatabaseCleaner.cleaning do
      example.run
    end
  end
end

在工厂中使用随机数据

使用Faker gem https://github.com/stympy/faker

FactoryGirl.define do
  factory :post do
    title { Faker::Lorem.word }
  end
end

我建议在每个规范示例运行之前手动清除数据库。当您的应用程序仍然很简单并且每个示例只创建一个或两个模型时,无需为您添加宝石。

答案 2 :(得分:0)

好的,所以我弄清楚为什么它没有保存新的Post记录。无论出于何种原因,本应被分配到:post工厂的帖子的作者都没有被创建。这意味着验证失败。

这是我正在使用的邮局:

FactoryGirl.define do
  factory :post do
    title { Faker::Lorem.sentence }
    excerpt { Faker::Lorem.paragraph }
    content { Faker::Lorem.paragraph }
    published false
    published_at nil
    post_type "article"
    keywords "blog, post, key, words"
    author
  end
end

这是我的:我的Devise Author模型的作者工厂:

FactoryGirl.define do
  factory :author do
    email { Faker::Internet.email }
    password "password"
    password_confirmation "password"
  end
end

当我使用FactoryGirl

生成属性时
attributes_for(:post)

方法,没有创建作者,因此没有设置帖子的author_id属性。

要解决此问题,我必须在测试中创建作者,然后在attributes_for方法中设置author_id属性。

所以我的工作测试现在看起来像这样:

it "saves the new Post in the database" do
  author = create(:author)
  expect{
    process :create, method: :post, params: { post: attributes_for(:post, author_id: author.id) }
  }.to change{Post.count}.by(1)  
end

虽然这解决了我原来的问题,但我不确定为什么在attributes_for电话中没有创建作者并与帖子相关联。