Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
612 views
in Technique[技术] by (71.8m points)

ruby - When to use curly braces vs parenthesis in expect Rspec method?

I had a test that did this:

expect(@parser.parse('adsadasdas')).to raise_error(Errno::ENOENT)

and it didn't work. I changed to:

expect { @parser.parse('adsadasdas') }.to raise_error(Errno::ENOENT)

And it worked.

When do we use curly braces and when do we use parentheses with expect?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In response to OP's comment, I've edited and completely rewritten my answer. I realize that my original answer was oversimplified, so much so that it could be considered incorrect.

Your question was actually addressed somewhat by this other StackOverflow question.

One poster, Peter Alfvin, makes a good point when he says:

As for rules, you pass a block or a Proc if you're trying to test behavior (e.g. raising errors, changing some value). Otherwise, you pass a "conventional" argument, in which case the value of that argument is what is tested.

The reason you're encountering the phenomenon you're seeing has to do with the raising of errors. When you pass @parser.parse('adsadasdas') as an argument (use parentheses) to expect, you are essentially telling ruby:

  1. Evaluate @parser.parse('adsadasdas') first.
  2. Take the result and pass this to expect.
  3. expect should see if this result matches my expectation (that is, that Errno:ENOENT will be raised).

But, what happens is: when ruby evaluates @parser.parse('adsadasdas'), an error is raised right then and there. Ruby doesn't even get a chance to pass the result on to expect. (For all we care, you could have passed @parser.parse('adsadasdas') as an argument to any function... like multiply() or capitalize()) The error is raised, and expect never even gets a chance to do its work.

But when you pass @parser.parse('adsadasdas') as a proc (a code block) to expect using curly braces, what you are telling ruby is this:

  1. expect, get ready to do some work.
  2. expect, I would like you to keep track of what happens as we evaluate @parser.parse('adsadasdas').
  3. Ok, expect, did the code block that was just evaluated raise a Errno:ENOENT error? I was expecting that it would.

When you pass a code block to expect, you are telling expect that you want it to examine the resulting behavior, the changes, made by your code block's execution, and then to let you know if it meets up to the expectations that you provide it.

When you pass an argument to expect, you are telling ruby to evaluate that argument to come to some value before expect even gets involved, and then you are passing that value to expect to see if it meets up to some expectation.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...