2014-03-13 4 views
0

Я новичок в Rspec и Capybara. Ошибка я получаю навигация с домашней страницы Домашняя галереяrspec: неопределенный метод `отзывы для ноля: NilClass

Сбой/Ошибка: посещение root_path

NoMethodError: неопределенный метод `свидетельства для ноль: NilClass

Я попытался пусть два различных пути для того, чтобы определите переменную в спецификации. Я добавил их обоих, чтобы получить обратную связь о том, что я делаю неправильно.

class WelcomeController < ApplicationController 
    def index 
     @event = Event.last 
     @event.testimonials.first ? @latest_testimonial = @event.testimonials.first.id : @latest_testimonial = nil 
    end 
end  

feature 'Navigation from homepage' do 

    before :each do 
     visit root_path 
     find('#nav-menu').find('h1').click #opens up navigation bar 
    end 

    scenario 'Visit Gallery' do 
     find('#nav-gallery').find('.no_bar').click 
     let(:event) {Event.last} #1st attempt at solving Rspec error. 
     let(:event) {mock_model(Event, id: 3, name: "Jack & Jill", date: "2004-06-10", created_at: "2014-03-10 02:57:45", updated_at: "2014-03-10 02:57:45")} #2nd attempt at solving Rspec error. 
     controller.stub(:event) 

     expect(page).to have_css 'img.photos' 
    end 
end 

ответ

2

Другой ответ правильный: здесь, по сути, это то же самое содержание в более простых (или, возможно, только более вытягиваемых объяснениях, которые вы уже знаете).

Первое ваше испытание делает выполнить before блок, который посещает root_path, предположительно, вызывая index действие на WelcomeController. Первое, что делает этот метод, - это вызов Event.last, который возвращает nil, потому что ваша тестовая база данных пуста, поэтому нет последней записи для возврата. Затем, когда вы вызываете testimonials на @event, вы получаете сообщение об ошибке, потому что @event is nil.

Чтобы исправить это, вам необходимо создать запись Event в базе данных, прежде чем перейти к root_path и вызвать действие index. Один из способов сделать это было бы, чтобы добавить эту строку перед visit root_path:

Event.create(name: "Jack & Jill" [...]) 

Это создаст запись в базе данных, поэтому Event.last будет возвращать что-то.

Вы также избавитесь от let заявлений и controller.stub. В настоящее время они не нужны (и в любом случае были другие проблемы). Этого должно быть достаточно, чтобы получить этот код, по крайней мере, для запуска.

На практике вы не найдете только записи, как я показал здесь, чтобы быть устойчивым подходом - здесь заходят фабрики (с помощью инструмента FactoryGirl) или mocks/stubs. Затем вы используете let для определения эти элементы только один раз в вашем блоке before, и все еще ограничивают накладные расходы, потребляя их, создавая их для последующих испытаний, где они фактически используются.

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

+0

Является ли использование mocks/stubs на тестах характеристик плохой практикой? Я пошел вперед и реализовал Factory Girl, как было предложено. – ltrainpr

+0

Мое предпочтение - использовать сохраненные объекты в тестах интеграции, но на мой взгляд, я не придаю большого значения.Обратите внимание, что с FactoryGirl вы можете создавать оштукатуренные версии ваших объектов, чтобы избежать попадания в db, где вы предпочитаете не делать этого. –

1

Event.last возвращает ноль.

Типичным (и самым простым) способом сделать это было бы просто создать событие в вашем тесте, прежде чем пытаться посетить сайт, а затем ваш контроллер будет его использовать. Спецификации функций должны действительно содержать минимальное количество насмешек и stubbing - они представляют реального пользователя, взаимодействующего с системой.

Ваши заглушки не привыкают (и на самом деле это ошибки сами по себе). Это подтверждается тем фактом, что ваша ошибка доходит до того, как они даже будут установлены.

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