如何使用' assert_difference'来为两个不同的对象断言两个不同的值?

时间:2015-03-17 14:14:59

标签: ruby-on-rails ruby

我在下面进行了以下测试:

it 'create action: a user replies to a post for the first time' do
  login_as user

  # ActionMailer goes up by two because a user who created a topic has an accompanying post.
  # One email for post creation, another for post replies.
  assert_difference(['Post.count', 'ActionMailer::Base.deliveries.size'], 2) do
    post :create, topic_id: topic.id, post: { body: 'Creating a post for the first time.' }
  end
  email = ActionMailer::Base.deliveries

  email.first.to.must_equal [user.email]
  email.subject.must_equal 'Post successfully created'
  must_redirect_to topic_path(topic.id)

  email.last.to.must_equal [user.email]
  email.subject.must_equal 'Post reply sent'
  must_redirect_to topic_path(topic.id)
end

由于代码中的assert_difference块,上面的测试会中断。为了使这个测试通过,我需要Post.count增加1,然后让ActionMailer::Base.deliveries.size增加2.那个场景将使测试通过。我试图将代码重写为第二种类型的测试。

it 'create action: a user replies to a post for the first time' do
  login_as user

  assert_difference('Post.count', 1) do
    post :create, topic_id: topic.id, post: { body: 'Creating a post for the first time.' }
  end

  # ActionMailer goes up by two because a user who created a topic has an accompanying post.
  # One email for post creation, another for post reply.
  assert_difference('ActionMailer::Base.deliveries.size', 2) do
    post :create, topic_id: topic.id, post: { body: 'Creating a post for the first time.' }
  end

  email = ActionMailer::Base.deliveries

  email.first.to.must_equal [user.email]
  email.subject.must_equal 'Post successfully created'
  must_redirect_to topic_path(topic.id)

  email.last.to.must_equal [user.email]
  email.subject.must_equal 'Post reply sent'
  must_redirect_to topic_path(topic.id)
end

第二次迭代接近我想要的但不完全。此代码的问题在于,由于assert_difference块中的创建调用,它将创建一个post对象两次。我查看了rails api指南中的assert_difference代码和这里找到的api dock(assert_difference API dock,但这不是我需要的。我需要这样的东西:

assert_difference ['Post.count','ActionMailer::Base.deliveries.size'], 1,2 do
   #create a post
end

有没有办法实现呢?

2 个答案:

答案 0 :(得分:7)

您可以嵌套它们,如下所示:

assert_difference("Post.count", 1) do
  assert_difference("ActionMailer::Base.deliveries.size", 2) do
    # Create a post
  end
end

答案 1 :(得分:0)

您还可以将Procs的哈希值传递给assert_difference方法,我认为这是推荐的方法。

assert_difference ->{ Post.count } => 1, ->{ ActionMailer::Base.deliveries.size } => 2 do
  # create post
end

您可以在文档here

中查看另一个示例