ruby-on-railsminitestassertraises

Rails MiniTest, Why doesn't this process as a success instead of an error?


[woo:~/Development … e-roles/test] master(+7/-3) 23s ± rails test
Running via Spring preloader in process 18905
Run options: --seed 34925

# Running:

E

Error:
UserTest#test_User_must_have_an_email_address:
ActiveRecord::RecordNotUnique: SQLite3::ConstraintException: UNIQUE constraint failed: users.email: INSERT INTO "users" ("created_at", "updated_at", "id") VALUES ('2019-05-16 23:08:53.696224', '2019-05-16 23:08:53.696224', 298486374)



bin/rails test test/models/user_test.rb:4



Finished in 0.019202s, 52.0779 runs/s, 0.0000 assertions/s.
1 runs, 0 assertions, 0 failures, 1 errors, 0 skips

Now, here is the user_test.rb

[woo:~/Development … e-roles/test] master(+7/-3) 1 ± cat models/user_test.rb
require 'test_helper'

class UserTest < ActiveSupport::TestCase
   test "User must have an email address" do
     user = User.new
     assert_raise SQLite3::ConstraintException   do
     user.save
     end
    end
end

I thought this would process as a success since I'm asserting that it is to raise a SQLite3::ConstraintException, which it does. I want to have the test succeed if the proper exception is raised. What am I doing wrong?


Solution

  • I think to get this test to pass, you'll want to assert about the Ruby exception, not the SQLite3 exception. Your ActiveRecord model (I'm guessing) is where the constraint is defined.

    Something like this:

    assert_raise ActiveRecord::RecordNotUnique do
      user.save
    end
    

    Asserting about the Ruby exception will make this test pass even if you switch to a different database in the future, which is one of the main reasons to use an ORM.