Rspec:合并的单元测试!Ruby散列中的方法
我有一段代码:Rspec:合并的单元测试!Ruby散列中的方法,ruby,unit-testing,rspec,Ruby,Unit Testing,Rspec,我有一段代码: requests.each do |request| request.each do |rqst| select_keys = ["author", "author_name"] selected_unit_req = rqst.select { |m| select_keys.include?(m) } user = Etl::Models::User.where(username: selected_unit_req["author"]["user
requests.each do |request|
request.each do |rqst|
select_keys = ["author", "author_name"]
selected_unit_req = rqst.select { |m| select_keys.include?(m) }
user = Etl::Models::User.where(username: selected_unit_req["author"]["username"] )
user.merge!({ author_name: selected_unit_req["author"]["name"] })
end
end
我无法测试合并!方法,在运行现有单元测试时获取nil:NilClass的
NoMethodError:undefined方法“[]”。有什么建议吗?让我们假设在您给出的示例中,rqst
返回一个空哈希值{}
当您设置所选的\u单元\u请求
时,它被设置为空哈希:
selected_unit_req = rqst.select { |m| select_keys.include?(m) }
=> {}
当您随后调用selected\u unit\u req[“author”]
时,将检查名为author
的键的散列,并返回nil
:
selected_unit_req["author"]
=> nil
因此,运行完整调用selected_unit_req[“author”][“username”]
可以被视为等同于以下内容:
nil["username"]
NoMethodError: undefined method `[]' for nil:NilClass
这就是错误被提出的原因;您希望selected\u unit\u req[“author”]
返回一个带有键username
的哈希值,但它返回的是nil
确保selected\u unit\u req
具有您首先期望的哈希键和值
更新
在下面的评论中,您询问了如何验证它是否具有所需的密钥。这个问题的答案取决于几件事,比如在没有它的情况下你希望看到什么行为,以及你正在使用的Ruby版本
我假设如果它没有键,并且您使用的是现代版本的Ruby(>=2.3.0),那么跳过rqst
是可以的
下面是一种使用哈希类的方法来完成此操作的方法:
request.each do |rqst|
next unless rqst.dig('author', 'username') && rqst.dig('author', 'name')
user = Etl::Models::User.where(username: rqst['author']['username'] )
user.merge!({ author_name: rqst['author']['name'] })
end
如果rqst
没有带有名为username
的子键和名为name
的子键的键author
,我们正在调用next
。这是因为如果哈希中没有这些键,dig
将返回nil
让我们假设一下,rqst=={}
。这条线的解释是:
next unless nil && nil
由于Ruby中有nil
,因此它最终调用next
跳过当前的rqst
值,并在迭代中转到下一个值
我还删除了selected_unit_req
,因为它是不必要的重复;由于您已经确切地知道希望从rqst
中得到什么键/值,因此无需仅使用这些值创建新的哈希;相反,您可以提取这些值,并在需要时直接使用它们。为什么要为另一个(内置)类的方法编写测试?从风格的角度来看。试图破译你的例子让我头疼。当我运行单元测试时,我遇到了以下错误NoMethodError:nil:NilClass的未定义方法“[]”您的示例太复杂了。首先简化它。您正在进行类似于十个方法调用的操作,将多个方法调用链接在一起,包括一个条件调用和一个rescue all。您显示的错误根本无助于破译它,因为您没有包含测试的代码,而且您在这一行中调用了四次[]
。使您的生活更轻松:将此代码重构为可读和合理的代码,然后进行测试。我正在修改我的代码(提供一个更简单的示例)。@Anotherm我刚刚添加了一段不同的代码。感谢您的回复,但我如何确保这一点?我对ruby很陌生,所以在理解这一点上有很多困难out@shitgetsreal我已经更新了我的答案,解释了这样做的方法。