Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I assert two different values for two different objects with 'assert_difference'?

I have the following test below:

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

The test above breaks because of the assert_difference block in the code. To make this test pass I need for Post.count to increment by 1 and then have ActionMailer::Base.deliveries.size to increment by 2. That scenario will make the test pass. I've tried to rewrite the code into this second type of test.

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

This second iteration is close to what I want but not quite. The problem with this code is that it will create a post object twice due to the create calls in the assert_difference block. I've looked at the assert_difference code in the rails api guide and api docks found here (assert_difference API dock but this is not what I need. I need something like this:

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

Is there a way to implement that?

like image 592
Dan Rubio Avatar asked Dec 05 '22 04:12

Dan Rubio


1 Answers

You can nest them, like this:

assert_difference("Post.count", 1) do
  assert_difference("ActionMailer::Base.deliveries.size", 2) do
    # Create a post
  end
end
like image 51
Matt Brictson Avatar answered Dec 22 '22 00:12

Matt Brictson