Rspec controller test does not match Apostrophe character?

I now have unit tests that do not work with the name of the company Faker.

It seems that expect(response.body).to match(@thing.name) is what is confusing.

When considering a mistake, Faker company names will sometimes have things like β€œO'Brian Company” or β€œO'Hare Company” or similar.

Is faker an encoded string? since I know that it is not a good idea to match the encoded strings, and I really do not want to just indicate the specific company name in using Factory im.

thanks

+6
source share
4 answers

Faker will not code you. It will just give you a string like O'Malley . But the answer should have HTML escaping (or some other kind, depending on the format), for example O'Malley . You can always puts response.body to verify this.

Compatibility RSpec matches really designed for the regular expression expected or actual , but in your case both lines. Since the code has an optimization calling values_match? which does a simple comparison , you effectively say expect(response.body).to eq(@thing.name) .

If you need a regular expression, you are correct that you need to be careful using uncontrolled values ​​to create it. Fortunately, Ruby has Regexp.escape , so you can say Regexp.new("foo" + Regexp.escape(@thing.name) + "bar") . But from your objection to include , it looks like you really want the answer to only contain a name, right? In this case, you do not need a regular expression.

In any case, the problem is not what is around the name, but how the name is escaped. Therefore, before comparing, you must either (1) decode the response or (2) encode the faker string. It doesn't really matter. Both are pretty easy:

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

or

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

Naturally, if your answer is JSON, you should replace all these HTML files with JSON, etc.

+5
source

You can try using #include instead of #match.

 expect(response.body).to include(@thing.name) 
+3
source

You can try passing regexp instead of the line:

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

Also, if the problem is only that you get this type of name from faker, then you should take a look at this QA , this gives some good ideas.

+2
source

Assuming you are linking to Faker :: Company Faker gem

The right way to make your wait example would be to use Regexp , as in the @ rafael-costa example. This eludes things like apostrophes.

The problem with using Faker is that your tests are not deterministic. It is best to provide static, known inputs for your test and expect the outputs to pass certain expectations based on these resources. It is hard to imagine a suitable example without additional information, but it could be something like this:

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

Also, as a rule, you should not test the specific output of the body in your controller specifications. To do this, check all goals. Usually you write a view test for this.

+2
source

Source: https://habr.com/ru/post/1014342/


All Articles