2015-12-02 3 views
0

У меня есть простое приложение Rails 4, и я пытаюсь написать несколько тестов, чтобы проверить, что моя учетная запись пользователя работает правильно. У меня есть проблема, что, когда я бегу testcases своими руками, все работает нормально, но когда я пишу некоторые тесты интеграции и запустить их он пропустит валидации моей модели, поэтому я получаю исключение базы данных, какПроверка и тестирование моделей Rails

Minitest::UnexpectedError: ActiveRecord::RecordNotUnique: PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_users_on_username" 


test 'unique username violated' do 
    params = user_params    # it is just a hash with User model attributes 
    User.new(params).save    # saving user first time to violate unique after   
    params[:email] = '[email protected]' 
    assert_no_difference 'User.count' do 
     post users_path, user: params 
    end 
    assert_template 'users/new' 
end 

Пример моей проверки ниже:

validates :username, :email, \ 
    uniqueness: {uniqueness: true, message: 'Username&email must be unique'}, \ 
    length: {maximum: 50, message: 'Length must be <= 50'} 

это не только эта проблема проверки, но все остальные не работают в тестах тоже.

Если я проверю свой объект пользователя с чем-то вроде внутри теста, он будет ложным, как и должно быть.

User.new(params).valid? 

Мои пользователи # создать действие ниже:

def create 
    @user = User.new user_params 
    if @user.save 
     flash[:success] = 'Welcome to the Sample App!' 
     redirect_to @user 
    else 
     render 'new' 
    end 
end 

мой пользователей # user_params метод:

def user_params 
    user_group = UserGroup.find_by_name 'administrator' 
    if user_group.nil? 
     user_group = UserGroup.new name: 'administrator' 
     user_group.save 
    end 
    {username: 'TestUsername', password: 'TestPassword', \ 
password_confirmation: 'TestPassword', email: '[email protected]', \ 
firstname: 'TestFirstname', lastname: 'TestLastname',user_group: user_group} 
end 
+0

попробовать уникальность: {сообщение: "Имя пользователя и адрес электронной почты должен быть уникальным} –

+0

хорошо, это то же самое, Ничего не изменилось. – AndreyS

+0

показать действие пользователя # create –

ответ

0

Rails валидация на самом деле не работает. При использовании:

validates :username, :email, uniqueness: true 

Вы добавляете аналогичные, но отдельные валидации для :username и :email. Рассмотрим этот случай:

user = User.new 
user.valid? 
assert(user.errors.has_key?(:username)) # pass 
assert(user.errors.has_key?(:email)) # pass 

При печати на ошибки с user.errors.full_messages() он будет содержать как Email has already been taken и Username has already been taken.

Но если вы переопределить сообщение следующим образом:

validates :username, :email, uniqueness: { message: 'Username&email must be unique' } 

Вы получите Username&email must be unique дважды вместо этого, что не так уж велика.

Если по какой-то причине вам действительно нужно иметь только одну ошибку вы бы добавить метод пользовательской проверки:

validate :uniqueness_of_username_and_email 

def uniqueness_of_username_and_email 
    if User.where("username = ? OR email = ?", username, email).any? 
    errors.add(:email_username, 'Username&email must be unique') 
    end 
end 
+0

Спасибо, я заметил, что он будет генерировать отдельный валидатор для каждого поля, но он все равно не работает. Проблема заключается не в том, как она работает, а в том, что она работает (!), Если работает как приложение, и я проверяю ее на своих представлениях, но это не сработает, если я проверю те же самые вещи с помощью тестов – AndreyS

+0

что дублирующее значение равно «null»? Типичный индекс уникальности postgres не допускает двух значений «null», но «проверяет уникальность» позволяет значение nil. – max

+0

Возможно, было бы легче устранить неполадки, если бы вы фактически выписали значение 'user_params' в своем тесте в качестве своего довольно ключевого фрагмента головоломки. – max

Смежные вопросы