gpt4 book ai didi

ruby - if + else 和 if -> unless 不一致

转载 作者:数据小太阳 更新时间:2023-10-29 06:53:50 24 4
gpt4 key购买 nike

我今天在定义我解决的自定义 RSpec 匹配器时遇到了一个问题,但实际上看不出任何一种方法有效而另一种方法无效的原因,这是代码:

方法 1——if + else:

RSpec::Matchers.define :have_success_message do |message|
match do |page|
if message.nil?
page.should have_selector('div.alert.alert-success')
else
page.should have_selector('div.alert.alert-success', text: message)
end
end
end

方法 2 -- if 后跟 unless

RSpec::Matchers.define :have_success_message do |message|
match do |page|
page.should have_selector('div.alert.alert-success') if message.nil?
page.should have_selector('div.alert.alert-success', text: message) unless message.nil?
end
end

我认为第一种方法更好,因为它只检查一次条件,但无论如何,结果应该是一样的,对吧?

好吧,事实证明第一种方法的测试通过了,而第二种方法的测试没有通过。我完全不知道为什么会这样,如果有人能对此有所了解,我会很高兴。

编辑:

忘记添加实际测试(使用方法 2):

存在以下 HTML 标记:

<div class="alert alert-success">Profile updated</div>

我运行 4 个独立的测试:

it { should have_success_message } # fails
it { should have_success_message('Profile updated') } # passes
it { should have_selector('div.alert.alert-success') } # passes
it { should have_selector('div.alert.alert-success', text: "Profile updated") } # passes

失败的消息如下:

1) User pages edit with valid information 
Failure/Error: it { should have_success_message }
expected #<Capybara::Session> to have success message
# ./spec/requests/user_pages_spec.rb:80:in `block (5 levels) in <top (required)>'

当 HTML 标签不存在时,所有 4 个测试都会失败。

编辑 2:

我尝试了另一种方法来验证控制流是否正确:

方法 3:

if message.nil?
puts "In if, message is: #{message.inspect}"
page.should(have_selector('div.alert.alert-success'))
end
unless message.nil?
puts "In unless, message is: #{message.inspect}"
page.should(have_selector('div.alert.alert-success', text: message))
end

使用这种方法的行为与方法 2 相同 - 第一个测试失败,然后第三次通过。

输出如下:

In if, message is: nil
In unless, message is: "Profile updated"

所以控制流看起来没问题,但是

page.should(have_selector('div.alert.alert-success'))

失败,即使它通过了匹配器之外。这真是一个谜。

最终编辑:

只是为了回应已批准的答案 - 当我这样切换代码时:

page.should have_selector('div.alert.alert-success', text: message) unless message.nil? 
page.should have_selector('div.alert.alert-success') if message.nil?

测试看起来像这样:

it { should have_success_message } # passes
it { should have_success_message('Profile updated') } # fails
it { should have_selector('div.alert.alert-success') } # passes
it { should have_selector('div.alert.alert-success', text: "Profile updated") } # passes

所以我认为确实最后一行,当它不是真的时,被评估为零,这导致了整个困惑。无论如何,第一种方法更好,但我很高兴我已经解决了这个问题:)

最佳答案

这是 RSpec 的正确行为,即使它看起来出乎意料。

考虑这段代码:

x = nil
"foo" if x.nil?
"bar" unless x.nil?
#=>
"foo"
nil

当条件为假时,...unless 语句返回 nil

在您的自定义匹配器中,当您的消息为 nil 时,...unless 语句返回 nil。

那是你的匹配 block 中的最后一行,所以你的匹配 block 返回 nil。

然后 RSpec 看到您的匹配 block 返回 nil,RSpec 认为这与 false 相同,因此 RSpec 报告您的自定义匹配器失败。

关于ruby - if + else 和 if -> unless 不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13663163/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com