rspec для тестирования формата response_to и csv

#ruby-on-rails #ruby #csv #ruby-on-rails-4 #rspec

#ruby-on-rails #ruby #csv #ruby-on-rails-4 #rspec

Вопрос:

Я хочу проверить, использует ли top_users eq User.top_users в моем контроллере rspec. Как мне получить доступ к format.csv? Мне нужно что-то вроде:

 it "format csv" do
  get :index, format: :csv
  # expect(something)……
end
  

Позже хочу протестировать csv: если формат файла правильный, без сохранения / загрузки.

Контроллер:

 def index
  respond_to do |format|  
    format.csv do
      top_users = User.top_users

      send_data(
        top_users.to_csv,
        filename: "top-users-#{Time.zone.today}.csv"
      )
    end
  end
end
  

Модель:

 def self.to_csv
  CSV.generate(headers: true) do |csv|
    csv << [‘one’, ‘two’]

    all.each do |user|
      csv << user.csv_data
    end
  end
end
  

csv_data — это: [user.name , user.email] или около того…

Комментарии:

1. Что произошло, когда вы попробовали пример спецификации, который вы показали нам здесь?

2. Хорошо, это не полное сообщение об ошибке… Не могли бы вы, пожалуйста, перейти к своим logfiles ( log/test.log ) и повторно запустить спецификацию, затем найти там ошибку и показать нам немного больше? Один момент: вы скопировали / вставили этот код непосредственно из своего приложения? вы заметили, что код в вашем вопросе имеет странное форматирование строк? Это потому, что в коде, который вы скопировали / вставили, используются странные «специальные» кавычки. Вполне вероятно, что интерпретатор ruby находит эти кавычки странными, например, он ожидает ' и находит ` вместо этого и думает, что строка также неправильно закрыта " против

Ответ №1:

Не имеет значения CSV, PDF или что-то еще, все дело в ответе, который вы получаете от запроса get в формате csv. Таким образом я тестирую свой генератор csv:

 describe "GET/index generate CSV" do
  before :each do
    get :index, format: :csv
  end

  it "generate CSV" do
    expect(response.header['Content-Type']).to include 'text/csv'
    expect(response.body).to include('what you expect the file to have')
  end
end
  

И это все.

Для каждого пользователя, который у вас есть, вы можете сделать что-то вроде этого:

  User.top_users.each do |user|
   expect(response.body).to include(user.name) # or the attr you want to check if it's in the file
 end
  

вы также можете добавить драгоценный камень ‘pry’, установить привязку.проверьте, прежде чем ожидать, и посмотрите ответ и какие элементы были бы полезны для вас, чтобы проверить, правильно ли работает метод, как вы ожидаете.

Комментарии:

1. я скопировал ваш код, и он выдает мне -> неопределенный метод `request=’

2. запрос =? Видите ли вы какой-либо метод запроса в моем или вашем коде!

3. format Аргумент является частью ActionController::TestCase , который агрессивно устаревает. Теперь рекомендуется использовать ActionDispatch::IntegrationTest which не имеет format аргумента.

Ответ №2:

Если вы столкнулись с ошибкой unknown keyword: :format , попробуйте следующее:

 describe "GET/index generate CSV" do    
  it "generate CSV" do
    get :index, params: {format: :csv}
    expect(response.header['Content-Type']).to include 'text/csv'
    expect(response.body).to include('what you expect the file to have')
  end
end
  

Комментарии:

1. Ключевое format слово неизвестно, потому что это только часть устаревшего тестового класса ActionController::TestCase , и нам рекомендуется переключиться на ActionDispatch::IntegrationTest . params: { format: :csv } работает, но это не идиоматично. Идиоматическое решение — использовать as: :csv аргумент, но для этого требуется зарегистрировать csv формат, чтобы Rails его распознал.

Ответ №3:

По крайней мере, с Rails 7 здесь происходит несколько вещей:

  1. Какой тест пишется? Существует тонкая разница между устаревшим ActionController::TestCase и новым ActionDispatch::IntegrationTest . Оба поддерживают as аргумент, но только устаревший ActionController::TestCase поддерживает format аргумент.
  2. as Аргумент не будет принят csv из коробки. Это связано с тем, что типы контента должны распознаваться ActionDispatch::RequestEncoder , и, по крайней мере, для меня, он знает только о :json , :identity и :turbo_stream . YMMV.

Чтобы заставить Rails распознавать формат CSV, вы должны зарегистрировать его следующим образом:

register_encoder :csv, param_encoder: -> params { params.to_s }

Источник: