assert_raise in Rails Integration Tests

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.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.