Testing uniqueness in a scope in a Rails project using shoulda (but not rspec)
Asked Answered
P

2

7

I have a user class with an email that is unique but scoped to the tenant:

class User < ActiveRecord::Base
  validates :email, :uniqueness => {:scope => :tenant_id, :allow_blank => true}
  #...
end

I'm trying to test it with:

class UserTest < ActiveSupport::TestCase
  context "a user" do
    setup { @user = create :user }
    subject { @user }

    should validate_uniqueness_of(:email).scoped_to(:tenant_id)
  end
end

but the test fails with this message:

Expected errors to include "has already been taken" when email is set to "[email protected]", got errors: ["email has already been taken (\"[email protected]\")", "first_name can't be blank (nil)", "last_name can't be blank (nil)"] (with different value of tenant_id)

which raises many questions. Why is the error message not matching? It seems because the actual email address is included in the error message, but why is it included? When I generate the error from the UI it doesn't seem to be included:

enter image description here

Also, at the end it says that it's trying it with a different tenant, which if it was true, it shouldn't generate any error (it doesn't when I run the app itself), but, why is it expecting the error? It should only expect the error if it's the same tenant_id.

This is so confusing. Any ideas what's going on and/or how to properly test this?

Predict answered 12/3, 2012 at 10:26 Comment(0)
O
15

Just ran into this same issue. We were able to resolve it by changing

should validate_uniqueness_of(:email).scoped_to(:tenant_id)

to

should validate_uniqueness_of(:email_id).scoped_to(:tenant_id)

Don't know if it's exactly the same situation, but apparently our issue was caused by nested resources throwing the matcher for a loop somehow.

Osset answered 2/8, 2012 at 23:53 Comment(0)
S
0

I find that the scoped_to has obscure issues with certain tests. Whenever encountered, it becomes necessary to write more verbose tests and manually test the failure to create an object in the same scope.

Sherrilsherrill answered 15/4, 2013 at 12:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.