Rspec控制器测试失败了撇号字符?

时间:2017-01-23 20:06:43

标签: ruby-on-rails rspec factory faker

现在我的单元测试失败了使用" Faker"公司名称。

好像expect(response.body).to match(@thing.name)似乎搞砸了。

在查看错误时,Faker公司的名称有时会包含" O' Brian Company"或者" O' Hare Company"或类似的。

faker是编码字符串吗?因为我知道匹配编码字符串并不是一个好主意,我真的不想在Factory im中指定一个特定的公司名称。

由于

4 个答案:

答案 0 :(得分: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)编码faker字符串。它并不重要。两者都很简单:

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

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

当然,如果您的响应是JSON,那么您应该用JSON等替换所有这些HTML转义内容。

答案 1 :(得分:3)

您可以尝试使用#include而不是#match。

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

答案 2 :(得分:2)

您可以尝试传递Regexp而不是字符串:

{{1}}

另外,如果问题出现在你从faker那里得到这种类型的名字时,你应该看看这个QA,它提供了一些很好的见解。

答案 3 :(得分:2)

假设您指的是Faker::Company宝石的Faker

使示例期望通过的正确方法是使用Regexp示例中的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)) 。这样做可以逃避像撇号这样的事情。

使用Faker的问题在于您的测试不是确定性的。最佳做法是为您的测试提供静态的已知输入,并期望输出根据这些输入通过某些期望。如果没有更多信息,很难提供相关的例子,但可能是这样的:

.selected

此外,您通常不应在控制器规格中测试特定的身体输出。这样做是为了跨目的进行测试。你通常会@rafael-costa

相关问题