2013-07-18 2 views
7

я использую:Как создать модель с определенным идентификатором с помощью RSpec и заводского девушка

gem 'rails', '3.2.11' 
gem 'rspec-rails', '2.13.2' 
gem 'webrat', '0.7.3' 
gem 'factory_girl_rails', '4.1.0' 
gem 'spork', '~> 0.9.0.rc' 

Я хочу, чтобы проверить мой HP, где у меня всегда есть связь с определенным пользователем, поэтому контроллер страниц для HP содержит:

@user = User.find(7) 

И вид HP содержит:

link_to 'See user', @user 

проблема заключается в том, что все тесты не так тестовая база данных не имеет U ser с id 7. Я попробовал:

FactoryGirl.define do 
    factory :user do 
    name "Testuser" 
    id "7" 
    end 
end 

... но это не работает. Существует всегда ошибка:

Спецификация такова:

describe "GET 'home'" do 

    before(:each) do 
     FactoryGirl.create(:user) 
    end 

    it "should be successful" do 
     get 'home' 
     response.should be_success 
    end 
end 

Сбой/Ошибка: получить 'дом' ActiveRecord :: RecordNotFound: Не удалось найти пользователя с идентификатором = 7

В действительности HP работает нормально, просто тест не удается. Как я могу заверить, что этот тест не потерпит неудачу?

+1

Я не уверен, что это сработает, но попробуйте id = 7 –

+0

Можете ли вы добавить код для своей неудачной спецификации, пожалуйста? –

+0

Покажите код вашей спецификации, если вам нужна полезная помощь. Пока все гадают. – boulder

ответ

8

насчет насмешливый/гася (гораздо быстрее спецификации, когда не экономя объекты в базу данных):

let(:user) { FactoryGirl.build(:user) } 
let(:id) { '1' } 

before do 
    user.stub(:id).and_return(id) # just to illustrate, not necessary if stubbing the find class method 
    User.stub(:find).and_return(user) 
end 

it { expect(user.id).to eq(id) } # just to illustrate 
it { expect(response).to be_success } 
it { expect(assigns(:user)).to eq(user) } 

Если у вас есть проблемы с пользователем быть только экземпляры, вы все еще можете использовать описанную выше технику, но заменить FactoryGirl.build(:user) по FactoryGirl.create(:user)

1

Вы можете установить идентификатор пользователя, делая что-то вроде

before 
    u = FactoryGirl.create(:user) 
    u.update_attribute(:id, 7) 
end 

Однако, это немного странно. Вы можете даже столкнуться с ситуацией, когда есть пользователь 7.

Что вы могли бы сделать, это использовать заглушки Rspec для получения нужного пользователя. Например, вы могли бы сделать что-то вроде

let(:user_7) { FactoryGirl.create(:user) } 
before { User.stub(:find).with(7).and_return(user_7) } 
+0

Спасибо. Ошибка update_attribute не изменила сообщение об ошибке ... Я попытаюсь использовать заглушки позже ... – user929062

8

На основе Using Factories части документации, я установил бы id в самой спецификации что-то вроде:

@user = FactoryGirl.create(:user, :id => 7) 
+1

Это звучит логично, но я все равно получаю то же сообщение об ошибке. – user929062

+3

Для тех, кто находит этот вопрос через Google. Это решение работает сейчас (август 2015) – Benj

2

не ответ, но в suspicition. .. вы, вероятно, не должны писать spec так, как вы это делаете.

в вашей спецификации сделать что-то вроде:

u=FactoryGirl.create(:user) 
User.where('id=?',u.id).count.should == 1 

Создание тесты в зависимости от конкретных идентификаторами рецепт для катастрофы.

+0

Я согласен с вами. Но проблема в том, что у моего HP есть ссылка на этого конкретного пользователя. Поэтому, когда я запускаю тест, ошибка заключается в том, что HP не отображается, поскольку в тестовой базе нет пользователя с идентификатором 7. Это единственный тест, который зависит от id, но я не вижу другого способа избежать этого. – user929062

0

В вашем случае я уверен, что вы просто проверяете, что вместо идентификатора используется идентификатор пользователя.

Когда я пишу тесты, я просто возвращаю идентификатор из базы данных, который намного надежнее и ближе к тому, что вы делаете в действительности.

Я бы назвал контроллер спецификацией примерно так.

RSpec.describe MyController, type: :controller do 
    let(:user) { FactoryGirl.create(:user) } 
    before do 
    # login the user here which would resolve which user id is being used 
    sign_in user #assumes you are using warden test helpers 
    get :home 
    end 

    it "allows the user to the page" do 
    assert_response :ok 
    end 
end 

Это должно нормально заряжаться. Если вы хотите проверить, правильно ли ссылка, вы должны сделать это в спецификации feature, используя что-то вроде capybara.