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



我有以下测试:

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块中的create调用,它将创建两次post对象。我已经查看了rails-api指南中的assert_difference代码和这里的api dock(assert_differenceneneneba api dock,但这不是我需要的。我需要这样的东西:

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

有办法实现吗?

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

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

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

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

您可以在此处的文档中查看另一个示例

最新更新