2017-01-23 80 views
6

現在我有單元測試失敗,使用「Faker」公司名稱。Rspec控制器測試失敗與撇號字符?

它似乎是expect(response.body).to match(@thing.name)是什麼越來越亂了。

在查看錯誤時,Faker公司名稱有時會包含諸如「O'Brian Company」或「O'Hare Company」或類似內容。

faker是編碼字符串嗎?因爲我知道在編碼字符串上匹配不是一個好主意,而且我真的不想只在Factory im using中指定特定的公司名稱。

謝謝

+0

我很好奇爲什麼你覺得我的回答是不夠的。我可以澄清的任何事情? –

+0

包含的問題是,如果它「包含」它,我希望它完全匹配它,而不僅僅是名稱中的「存在」一詞。雖然我可能會用它作爲回退,在這種情況下,你的回答正確:)。我真的只是在尋找其他的可能性。 – 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)編碼faker字符串。這並不重要。兩者都是相當容易:

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

你可以試着通過,而不是字符串正則表達式:

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

而且,如果問題是隻有當你得到這種類型的騙子的名字,那麼你應該看看這個QA,它提供了一些很好的見解。

+0

我想不使用它的問題,我需要定義大量的樣本測試數據。但從某種角度來看,這很好,因爲它確實顯示了奇數值的問題。 – msmith1114

2

假設你是指在Faker寶石

Faker::Company正確的方法,使您的例子期望通將使用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