2017-01-23 79 views
6

W tej chwili mam testy jednostkowe, które zawodzą przy użyciu nazwy firmy "Faker".Test kontrolera Rspec zawodzi z postacią Apostrophe?

Wygląda na to, że to expect(response.body).to match(@thing.name).

Kiedy patrzysz na błąd, nazwy firm Faker czasami zawierają takie rzeczy jak "O'Brian Company" lub "O'Hare Company" lub podobne.

Czy faker jest zakodowanym ciągiem znaków? ponieważ wiem, że nie jest dobrym pomysłem dopasowanie się do zakodowanych łańcuchów i naprawdę nie chcę po prostu określać konkretnej nazwy firmy w urządzeniu Factory im.

Dzięki

+0

Jestem ciekawy, dlaczego uważasz, że moja odpowiedź nie była wystarczająca. Czy mogę coś wyjaśnić? –

+0

Problem z włączeniem jest taki, że jeśli "zawiera" go, chcę, aby pasował do niego całkowicie, a nie tylko, że słowo "istnieje" w nazwie. Chociaż mogę go używać jako zabezpieczenia, w którym źle zaznacz swoją odpowiedź poprawną :). Naprawdę staram się po prostu szukać innych możliwości. – msmith1114

Odpowiedz

5

Faker nie zrobi dla ciebie żadnego kodowania. Po prostu da ci ciąg znaków, taki jak O'Malley. Ale odpowiedź powinna zawierać kod HTML (lub inny rodzaj, w zależności od formatu), taki jak O'Malley. Zawsze możesz zobaczyć na pewno puts response.body.

Matówka RSpec matches jest naprawdę zaprojektowana for either expected or actual to be a regular expression, ale w twoim przypadku oba są ciągami. Ponieważ kod has an optimization calling values_match?, który does a simple comparison, skutecznie mówi się: expect(response.body).to eq(@thing.name).

Jeśli chcesz mieć wyrażenie regularne, masz rację, że powinieneś być ostrożny przy użyciu niekontrolowanych wartości, aby go utworzyć. Na szczęście Ruby ma do tego Regexp.escape, więc możesz powiedzieć Regexp.new("foo" + Regexp.escape(@thing.name) + "bar"). Ale z twojego sprzeciwu wobec include, brzmi to tak, jakbyś chciał, żeby odpowiedź zawierała tylko imię, prawda? W takim przypadku nie potrzebujesz w ogóle żadnego wyrażenia regularnego.

W każdym razie problem nie dotyczy tego, co jest wokół nazwy, ale jak nazwa jest ukryta. Dlatego przed porównaniem powinieneś (1) zdekodować odpowiedź lub (2) zakodować ciąg faker. To naprawdę nie ma znaczenia, które. Oba są dość proste:

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

lub

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

Naturalnie, jeśli odpowiedź jest JSON, należy wymienić te wszystkie rzeczy HTML ucieczki z JSON, itp

+0

Szybkie pytanie: Co to jest CGI w swoich "oczekiwaniach"? Czy to właśnie je koduje? – msmith1114

+0

CGI jest częścią standardowej biblioteki Ruby: https://ruby-doc.org/stdlib-2.3.0/libdoc/cgi/rdoc/CGI.html –

3

Możesz spróbować użyć #include zamiast używać #match.

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

można spróbować przechodzącą REGEXP zamiast napisu:

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

Również Jeśli problem jest tylko wtedy, gdy pojawi się ten typ nazwisk z faker, to należy spojrzeć na to QA, Daje to kilka dobrych wglądów.

+0

Domyślam się, że problem z NIE używanie go, to musiałbym zdefiniować wiele przykładowych danych testowych. Ale w pewnym sensie jest to dobre, ponieważ pokazuje na przykład problemy z wartościami nieparzystymi. – msmith1114

2

Zakładając, że odnosimy się do Faker::Company z Faker gem

Prawidłowym sposobem wykonania przykładowego przejścia oczekiwania będzie użycie Regexp jak w przykładzie @rafael-costa. Robi to wymyka się od apostrofów.

Problem z używaniem Fakera polega na tym, że twoje testy nie są deterministyczne.Najlepszą praktyką jest dostarczanie statycznych, znanych danych wejściowych do testu i oczekiwanie, że wyniki będą przekazywać określone oczekiwania w oparciu o te dane wejściowe. Trudno jest dostarczenie istotnych przykład bez więcej informacji, ale być może coś takiego:

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)) 

Również zazwyczaj nie powinien przetestować konkretne wyjście ciała w twoich specyfikacji kontrolera. Aby to zrobić, testujemy w różnych celach. Zwykle byłby to write a view test.