Today I wanted to assert that a POST from an integration test resulted in an exception being raised under certain conditions. I had done this bunch of times in unit and controller tests, so I just ported that methodology to my integration test. Here is a contrived example of how my original test read:
def test_that_exception_is_raised exception = assert_raise(RuntimeError) { post '/comments', {:comment => {:message => 'I hate you!'}} } assert_equal 'Say something nicer please. Thank you.', exception.message end
The problem was that the assertions were failing because <RuntimeError> exception expected but none was thrown.
But I clearly saw in my test.log
that the exception was thrown:
RuntimeError (Say something nicer please. Thank you.): app/controllers/comments_controller.rb:789:in `create' test/integration/comments_test.rb:456:in `__bind_1278520981_664592' /ruby/lib/ruby/8.8/test/unit/assertions.rb:123:in `assert_raise'
I thought about about the differences between functional and integration tests in Rails, and then realized that although the exception was thrown, that’s not what is returned to the browser. Instead, the browser is sent an error page. Then it became glaringly-obvious, how to write my assertion:
def test_that_exception_is_raised post '/comments', {:comment => {:message => 'I hate you!'}} assert_response :error, 'Say something nicer please. Thank you.' end
I still feel like a newbie sometimes.