Consider the following call to a controller that you wish to test:
Let’s say that you want to test that the code works as expected when the Event ID is invalid (it could be that no such record exists or that the record belongs to another user, etc.). So you want to test that it raises ActiveRecord::RecordNotFound, and you also want to test that it redirects to the right place or renders the right template, and you want to test that the http status indicates failure.
The obvious way to test for an exception is something like
describe “failures” do
it “throws an exception” do
expect { get 'show', id: @event1.id }.to raise_exception(ActiveRecord::RecordNotFound) end
end
But the obvious way to test for the side effects would be something like
describe “failures” do
before(:each) do
end
it “signals failure” do
expect(response).to_not be_success
end
it “renders the correct template” do
expect(response).to render_template(:index)
end
end
or, the shorter but probably less desirable (because you would get the same failure message for three different errors
it “fails appropriately” do
expect(response).to_not be_success
expect(response).to render_template(:index)
end
But neither of these forms mixes well with the exception checker example at the top. In the interest of DRYing my example, I don’t want to repeat the “get” command. So one thought on how to DRY it up would be the following:
it “fails appropriately” do
expect { get 'show', id: @event1.id }.to raise_error(ActiveRecord::RecordNotFound)
expect(response).to_not be_success
expect(response).to render_template(:index)
end
but, as stated before, the failure messages are not very specific. So how can I combine exception checking with side-effect checking with specific messages for each test in a way that is DRY?
Thanks for staying with this question all the way through!