如何解决“RSpec::Expectations::ExpectationNotMetError: expected”错误?

Posted

技术标签:

【中文标题】如何解决“RSpec::Expectations::ExpectationNotMetError: expected”错误?【英文标题】:How to resolve "RSpec::Expectations::ExpectationNotMetError: expected" error? 【发布时间】:2016-03-01 15:17:38 【问题描述】:

我正在从 XML 中提取一个值并使用该值来检查它是否存在于 PDF 文件中:

我拥有的 XML 是

<RealTimeLetter>
 <Customer>
    <RTLtr_Acct>0163426</RTLtr_Acct>
    <RTLtr_CustomerName>LSIH JHTWVZ</RTLtr_CustomerName>
    <RTLtr_CustomerAddress1>887 YPCLY THYZO SU</RTLtr_CustomerAddress1>
    <RTLtr_CustomerAddress2 />
    <RTLtr_CustomerCity>WOODSTOCK,</RTLtr_CustomerCity>
    <RTLtr_CustomerState>GA</RTLtr_CustomerState>
    <RTLtr_CustomerZip>30188</RTLtr_CustomerZip>
    <RTLtr_ADAPreference>NONE</RTLtr_ADAPreference>
    <RTLtr_Addressee>0</RTLtr_Addressee>
 </Customer>
</RealTimeLetter>

PDF 文件包含客户名称和地址

LSIH JHTWVZ
887 YPCLY THYZO SU
WOODSTOCK, GA 30188

我正在使用 PDF Reader 和 Nokogiri gems 从 PDF 中读取文本,从 XML 中提取客户名称并检查 PDF 中是否包含客户名称。

PDF阅读器被解析为

require 'pdf_reader'

  def parse_pdf
    PDF::Reader.new(@filename)
  end

 @reader = file('C:\Users\ecz560\Desktop\30004_Standard.pdf').parse_pdf

require 'nokogiri'

@xml = Nokogiri::XML(File.open('C:\Users\ecz560\Desktop\30004Standard.xml'))

@CustName = @xml.xpath("//Customer[RTLtr_Loancust='0163426']//RTLtr_CustomerName").map(&:text).to_s
 page_index = 0
 @reader.pages.each do |page|
 page_index = page_index+1
   if expect(page.text).to include  @CustName
     valid_text = "Given text is present in -- #page_index"
     puts valid_text
   end
 end

但我收到一个错误:

RSpec::Expectations::ExpectationNotMetError: expected "LSIH JHTWVZ\n        887 YPCLY THYZO SU\n               WOODSTOCK, GA 30188\n                                                                                                                                  Page 1 of 1" to include "[\"LSIH JHTWVZ\"]"
Diff:
@@ -1,2 +1,80 @@
-["LSIH JHTWVZ"]

+        LSIH JHTWVZ
+        887 YPCLY THYZO SU                                                   
+        WOODSTOCK, GA 30188                                                  

./features/step_definitions/Letters/Test1_Letters.rb:372:in `block (2 levels) in <top (required)>'
./features/step_definitions/Letters/Test1_Letters.rb:370:in `each'
./features/step_definitions/Letters/Test1_Letters.rb:370:in `/^I validate the PDF content$/'
C:\Users\ecz560\Documents\GitHub\ATDD Local\features\FeatureFiles\Letters\Test1_Letters.feature:72:in `Then I validate the PDF content'

在理解问题在于我比较@Custname 的方式上。 我该如何解决这个问题?

【问题讨论】:

欢迎来到 Stack Overflow。请阅读“minimal reproducible example”。我们没有足够的信息来帮助您,我们无法复制问题。您没有向我们展示完整的错误信息。作为旁注,您对实例变量的使用表明您不了解如何使用它们。此外,在 Ruby 中,我们不会将 @CustName 之类的名称用于变量或常量。 我用所有必需的信息编辑了问题。 【参考方案1】:

我看到的一件事是您的 XPath 选择器不起作用。

//Customer[RTLtr_Loancust='0163426']//RTLtr_CustomerName

测试它:

require 'nokogiri'

doc = Nokogiri::XML(<<EOT)
<RealTimeLetter>
<Customer>
    <RTLtr_Acct>0163426</RTLtr_Acct>
    <RTLtr_CustomerName>LSIH JHTWVZ</RTLtr_CustomerName>
    <RTLtr_CustomerAddress1>887 YPCLY THYZO SU</RTLtr_CustomerAddress1>
    <RTLtr_CustomerAddress2 />
    <RTLtr_CustomerCity>WOODSTOCK,</RTLtr_CustomerCity>
    <RTLtr_CustomerState>GA</RTLtr_CustomerState>
    <RTLtr_CustomerZip>30188</RTLtr_CustomerZip>
    <RTLtr_ADAPreference>NONE</RTLtr_ADAPreference>
    <RTLtr_Addressee>0</RTLtr_Addressee>
</Customer>
</RealTimeLetter>
EOT

doc.search("//Customer[RTLtr_Loancust='0163426']//RTLtr_CustomerName").to_xml # => ""

使用一点修改找到&lt;Customer&gt; 节点:

doc.search('//Customer/RTLtr_Acct/text()[contains(., "0163426")]/../..').to_xml

# => "<Customer>\n    <RTLtr_Acct>0163426</RTLtr_Acct>\n    <RTLtr_CustomerName>LSIH JHTWVZ</RTLtr_CustomerName>\n    <RTLtr_CustomerAddress1>887 YPCLY THYZO SU</RTLtr_CustomerAddress1>\n    <RTLtr_CustomerAddress2/>\n    <RTLtr_CustomerCity>WOODSTOCK,</RTLtr_CustomerCity>\n    <RTLtr_CustomerState>GA</RTLtr_CustomerState>\n    <RTLtr_CustomerZip>30188</RTLtr_CustomerZip>\n    <RTLtr_ADAPreference>NONE</RTLtr_ADAPreference>\n    <RTLtr_Addressee>0</RTLtr_Addressee>\n</Customer>"

此时很容易从&lt;Customer&gt; 中的元素中获取内容:

customer = doc.search('//Customer/RTLtr_Acct/text()[contains(., "0163426")]/../..')
customer.at('RTLtr_Acct').text # => "0163426"
customer.at('RTLtr_CustomerAddress1').text # => "887 YPCLY THYZO SU"

【讨论】:

我可以通过使用@CustName = @xml.xpath("//Customer[RTLtr_Loancust='0163426']//RTLtr_CustomerName").map(&:tex‌​t) 来解决这个问题.first 是的,这会起作用,但这不是你应该如何编写选择器。 // 表示从 DOM 顶部开始向下搜索。所以你说从顶部开始找到Customer 然后从顶部开始找到RTLtr_CustomerName,而不是在Customer 中找到RTLtr_CustomerName//RTLtr_CustomerName 的完整选择器将使用给定的 XML 示例完成相同的操作,但如果您需要特定的客户,更复杂的示例将导致它失败。 我在 XML 文件中尝试了多个客户,它为我提供了我需要的元素。我的 XML 总是很简单。如果我有任何问题,我会尝试你的建议。谢谢你:)【参考方案2】:

if expect(page.text).to include @CustName

expect 不是这样使用的。

    在测试中使用期望值来验证您的代码是否按应有的方式工作。它不应该在正常代码中使用。

    预期会引发异常并在失败时停止所有代码。它不会返回 true/false - 如果失败,您将无法继续 - 它会像在您的代码中那样(正确地)抛出异常,然后您的所有代码都将停止并且不会再次启动。

您可能想要做的只是检查这样的值:

if page.text.includes?(@CustName)

(注意:我没有对此进行错误测试......您可能需要在谷歌上搜索正确的编写方式并编写类似的实际工作。)

【讨论】:

这里的问题是我存储在@custName 中的值是一个数组 ["LSIH JHTWVZ"]。但我想将它存储为字符串“LSIH JHTWVZ”。我无法找到如何从 XML 中提取元素作为字符串。 1) 这不是您唯一的问题;) 2) 为什么不直接执行以下操作:@custName = @custName.first 从数组中提取字符串? @CustName = @xml.xpath("//Customer[RTLtr_Loancust='0163426']//RTLtr_CustomerName").map(&amp;:text).first 使用@CustName = @xml.xpath("//Customer[RTLtr_Loancust='0163426']//RTLtr_CustomerName").map(&:tex‌​t).first 工作。 如果你能把它放在你的答案中,我可以接受。谢谢你:)

以上是关于如何解决“RSpec::Expectations::ExpectationNotMetError: expected”错误?的主要内容,如果未能解决你的问题,请参考以下文章

云原生景观:可观察性和分析解决了什么问题?如何解决的?

如何解决 Ajax 跨域请求不到的问题

如何解决包冲突问题

如何解决包冲突问题

如何解决ajax跨域问题

MySQL 的 10048问题,如何解决?