Reputation: 4897
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?
Upvotes: 8
Views: 3667
Reputation: 139
You can also pass a hash of Procs to the assert_difference
method, which I believe would be the recommended way.
assert_difference ->{ Post.count } => 1, ->{ ActionMailer::Base.deliveries.size } => 2 do
# create post
end
You can check another example in the docs here
Upvotes: 11
Reputation: 11082
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
Upvotes: 17