2017-01-23 19 views
6

Прямо сейчас у меня есть модульные тесты, которые не работают с именем компании «Faker».Тест контроллера Rspec не соответствует характеру Apostrophe?

похоже, что expect(response.body).to match(@thing.name) - это что-то перепутано.

При взгляде на ошибку имена компаний Faker иногда имеют такие вещи, как «O'Brian Company» или «O'Hare Company» или аналогичные.

Является ли фейкер закодированной строкой? поскольку я знаю, что это не очень хорошая идея для сопоставления закодированных строк, и я действительно не хочу просто указывать конкретное название компании в Factory im using.

Thanks

+0

Мне любопытно, почему вы чувствовали, что мой ответ был недостаточным. Что я могу прояснить? –

+0

Проблема с include заключается в том, что если он «содержит» его, я хочу, чтобы он полностью соответствовал ему, а не только слово «существует» внутри имени. Хотя я могу использовать его в качестве резервной копии, в которой неправильный ответ на ваш ответ правильный. Я действительно просто пытаюсь найти другие возможности. – msmith1114

ответ

5

Faker не будет кодировать для вас. Он просто даст вам строку, такую ​​как O'Malley. Но ответ должен иметь HTML-экранирование (или какой-либо другой вид, в зависимости от формата), например O'Malley. Вы всегда можете найти puts response.body, чтобы убедиться в этом.

Совместимость RSpec matches действительно разработан for either expected or actual to be a regular expression, но в вашем случае оба являются строками. Потому что код has an optimization calling values_match?, который does a simple comparison, вы фактически говорите expect(response.body).to eq(@thing.name).

Если вы хотите получить регулярное выражение, вы правы, что вы должны быть осторожны с использованием неконтролируемых значений для его создания. К счастью, у Ruby есть Regexp.escape, поэтому вы можете сказать Regexp.new("foo" + Regexp.escape(@thing.name) + "bar"). Но от вашего возражения до include это звучит так, будто вы действительно хотите, чтобы в ответе содержалось только имя, не так ли? В этом случае вам не нужно регулярное выражение вообще.

В любом случае проблема не в том, что такое вокруг имя, но как имя скроется. Поэтому перед сравнением вы должны либо (1) декодировать ответ, либо (2) закодировать строку фейкера. На самом деле это не имеет значения. И довольно легко:

expect(CGI.unescapeHTML(response.body)).to eq @thing.name 

или

expect(response.body).to eq CGI.escapeHTML(@thing.name) 

Естественно, если ваш ответ JSON, вы должны заменить весь этот HTML вытекающего материал с JSON и т.д.

+0

Быстрый вопрос: что это за CGI в ваших «ожидающих» функциях. Это что кодирует их? – msmith1114

+0

CGI является частью стандартной библиотеки Ruby: https://ruby-doc.org/stdlib-2.3.0/libdoc/cgi/rdoc/CGI.html –

3

Вы можете попробовать использовать #include вместо #match.

expect(response.body).to include(@thing.name) 
2

Вы можете попробовать пропусканием Regexp вместо строки:

expect(response.body).to match(Regexp.new(@thing.name)) 

Кроме того, если проблема только тогда, когда вы получите этот тип имен из FAKER, то вы должны смотреть на это QA, Он дает некоторые хорошие идеи.

+0

Я предполагаю, что проблема не используется, я должен определить множество тестовых данных. Но в некотором смысле это хорошо, потому что он показывает проблемы с нечетными значениями, например. – msmith1114

2

Предполагая, что вы имеете в виду Faker::CompanyFaker gem

Правильный способ сделать ваш пример ожидания будет состоять в использовании Regexp как в примере @rafael-costa. Это ускользает от таких вещей, как апострофы.

Проблема с использованием Faker заключается в том, что ваши тесты не детерминированы.Лучше всего предоставлять статические, известные входы для вашего теста и ожидать, что выходы пройдут определенные ожидания на основе этих ресурсов. Трудно представить уместный пример без дополнительной информации, но может быть что-то вроде этого:

company = Company.new(name: 'Acme Anvils') 
get :show, params: {id: company.to_param}, session: {} 
expect(response.body).to match(Regexp.new('Acme Anvils', Regexp::MULTILINE)) 

Также вы обычно не должны проверять конкретный выход тела в пределах вашего контроллера спецификации. Для этого нужно проверить все цели. Для этого вы обычно должны write a view test.

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

  • Нет связанных вопросов^_^