Методы тестирования с использованием gon с rspec

У меня есть функция, которая отправляет переменную в JS с помощью Gon.

def calc_foo
  # calculate foo
  gon.foo = foo
end

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

it "should return bar" do
  foo = @foo_controller.calc_foo
  expect(foo).to eq(bar)
end

Но я получаю следующее сообщение об ошибке, когда контрольный пример достигает строки, где переменная отправляется в gon.

Failure/Error: foo = @foo_controller.calc_foo
 NoMethodError:
   undefined method `uuid' for nil:NilClass

Я проверил значение для foo, и это не Nil, поэтому должен быть Nil. Я полагаю, что ошибка в том, что я не правильно понимаю. Это rspec-часть моего Gemfile

#rspec-rails includes RSpec itself in a wrapper to make it play nicely with Rails. 
#Factory_girl replaces Rails’ default fixtures for feeding test data
#to the test suite with much more preferable factories.
group :development, :test do
  gem 'rspec-rails'
  gem 'factory_girl_rails'
  gem 'capybara'
  gem 'gon'
end

Так как я могу заставить rspec хорошо играть с Гоном? (Я также пытался включить gon в мой spec-файл, но безуспешно)

2 ответа

В спецификации контроллера (где gon принадлежит) вам нужно сделать фактический запрос, чтобы обойти вашу проблему:

RSpec.describe ThingiesController do
  let(:gon) { RequestStore.store[:gon].gon }

  describe 'GET #new' do
    it 'gonifies as expected' do
      get :new, {}, valid_session # <= this one
      expect(gon['key']).to eq :value
    end
  end
end

Если вы не хотите придерживаться определенных controller или же action для gon связанные характеристики (скажем, у вас есть gon метод в вашем ApplicationController), вы можете использовать анонимный подход контроллера:

RSpec.describe ApplicationController do
  let(:gon) { RequestStore.store[:gon].gon }

  controller do
    # # Feel free to specify any of the required callbacks,
    # # like
    # skip_authorization_check
    # # (if you use `CanCan`) 
    # # or
    # before_action :required_callback_name

    def index
      render text: :whatever
    end
  end

  describe '#gon_related_method' do
    it 'gonifies as expected' do
      get :index
      expect(gon['key']).to eq :value
    end
  end
end

У меня много controller а также request / integration спецификации и может подтвердить, что gon ведет себя хорошо там, пока вы делаете реальные запросы.

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

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

Контроллер устанавливает массив объектов - например, gon.map_markers = [...]

Моя спецификация запроса извлекает JSON через регулярное выражение (.split() а также match_array обработать порядок-независимый-массив-несс):

....

# match something like
#   gon.map_markers=[{"lat":a,"lng":b},{"lat":c,"lng":d},...];
# and reduce/convert it to
#   ['"lat":a,"lng":b',
#    '"lat":c,"lng":d',
#    ...
#   ]
actual_map_markers = response.body
                     .match('gon.map_markers=\[\{([^\]]*)\}\]')[1]
                     .split('},{')

expect(actual_map_markers).to match_array expected_map_markers
Другие вопросы по тегам