Do you think it would look cleaner?

I was looking over some of my specs.
I was thinking that the following:

@game.should_receive(:name).and_return(‘The Battle for Blaze’)
@game.should_receive(:people).and_return(5000000)
@game.should_receive(:activated).and_return(true)

Would it look cleaner if I could do this instead?

@game.should_recieve_and_return(
:name => ‘The Battle for Blaze’
:people => 5000000
:activated => true)

Opinions?

On Dec 28, 2007 11:00 PM, Andrew WC Brown [email protected] wrote:

:name => ‘The Battle for Blaze’
:people => 5000000
:activated => true)

Opinions?


rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users

Two thoughts as to why I wouldn’t use this…

  1. One expectation per example
  2. Stub queries, expect commands

Your way is clean though. How do you handle arguments?

Pat

eg.
I’m going to the store to buy one milk
I’m going to the store to buy one bagel
I’m going to the store to buy one coffee

@shopping_list.should_receive(:milk).once.and_return(‘milk’)
@shopping_list.should_receive(:bagel).once.and_return(‘bagel’)
@shopping_list.should_receive(:coffee).once.and_return(‘coffee’)

I going to the store to buy one:

  • milk
  • bagel
  • coffee

@shopping_list.should_receive_the_following(
:milk => ‘milk’
:bagel => ‘bagel’
:coffee => ‘coffee’
).once

For the shopping list I describe its expected that they all have the
same
expectations.
I’m still reading the rspec source.

I would think of creating a new method called:
should_receive_the_following
but seeing how the message_expectations work not sure how plausible it
would
be to implement.

You wouldn’t expect to return something:

@shopping_list.should_receive_the_following(
:milk => ‘milk’
:bagel => ‘bagel’
:coffee => ‘coffee’
).once.and_return(@list)

It boggles my mind. I haven’t done too much meta programming.

I just see these large blocks of:

@shopping_list.should_receive(:milk)…and_return(‘milk’)
@shopping_list.should_receive(:bagel).and_return(‘bagel’)
@shopping_list.should_receive(:coffee).and_return(‘coffee’)

and it would be much clearer if I could list them in a hash instead.

El sáb, 29 de dic de 2007, a las 02:00:25 -0500, Andrew WC Brown dijo:

:name => ‘The Battle for Blaze’
:people => 5000000
:activated => true)

Opinions?

Hi Andrew, I think the first option is more clearer and more expresive
than then 2nd. one.


rspec-users mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users


Gastón Ramos

“I always thought Smalltalk would beat Java, I just didn’t know it would
be
called ‘Ruby’ when it did.”

– Kent Beck

GNU/Linux Counter user #450312

No a la Matricula Obligatoria

On Dec 29, 2007 6:00 PM, Andrew WC Brown [email protected] wrote:

I just see these large blocks of:

@shopping_list.should_receive(:milk)…and_return(‘milk’)
@shopping_list.should_receive(:bagel).and_return(‘bagel’)
@shopping_list.should_receive(:coffee).and_return(‘coffee’)

and it would be much clearer if I could list them in a hash instead.

It would definitely be less typing, but I don’t think it would be as
clear in terms of intent.

We do have a similar syntax to what you’re looking for for stubs:

list = stub(“list”,
:milk => ‘milk’
)

This makes sense to me for stubs for a couple of reasons. One is that
it is similar to the syntax for creating an OpenStruct, which should
be familiar to any ruby developer.

If we were to do the same with expectations we lose two things. Most
importantly is the line number of the failure when one occurs. Also,
and_return is already problematic for me after should_receive because
it implies an expectation - it should receive this and it should
return that, as opposed to it should receive this and when it does go
ahead and return that so that the example can keep moving :slight_smile: Combining
these two concepts into one method name would make this even more
confusing in my perception.

There are other mock frameworks that might come closer to the
terseness you desire. You should check out mocha and RR
(RubyPub.com is for sale | HugeDomains) if that’s what you’re looking for.
They both offer a different “feel” from rspec’s framework and some
different features as well.

HTH,
David

On Dec 29, 2007 1:29 PM, Pat M. [email protected] wrote:

@game.should_recieve_and_return(
:name => ‘The Battle for Blaze’
:people => 5000000
:activated => true)

Opinions?

I find this more confusing. When I first read it I thought it was
going to receive the hash as arguments and return the hash. I think
the expressiveness of “should_receive(…).and_return(…)” wins in
this case,

2007/12/29, Andrew WC Brown [email protected]:

I just see these large blocks of:

@shopping_list.should_receive(:milk)…and_return(‘milk’)
@shopping_list.should_receive(:bagel).and_return(‘bagel’)
@shopping_list.should_receive(:coffee).and_return(‘coffee’)

and it would be much clearer if I could list them in a hash instead.

What about :

{
:milk => ‘milk’,
:bagel => ‘bagel’,
:coffee => ‘coffee’
}.each do |method, value|
@shopping_list.should_receive(method).and_return(value)
end

So it doesn’t need a #should_receive_the_following method.

– Jean-François.

On Dec 30, 2007 6:52 AM, Jean-François Trân [email protected] wrote:

What about :

{
:milk => ‘milk’,
:bagel => ‘bagel’,
:coffee => ‘coffee’
}.each do |method, value|
@shopping_list.should_receive(method).and_return(value)
end

So it doesn’t need a #should_receive_the_following method.

You can certainly do that (and I have), but again, you’d lose the
benefit of a unique line number in the failure message.

This is something that is often lost under the banner of DRY. DRY
doesn’t mean “type as few characters as you can.” It means don’t
repeat functionality or knowledge within a system. IMO, multiple calls
to the same methods, but with different data, are NOT duplication in
this sense.

On Dec 30, 2007 10:04 AM, David C. [email protected] wrote:

So it doesn’t need a #should_receive_the_following method.

You can certainly do that (and I have), but again, you’d lose the
benefit of a unique line number in the failure message.

This is something that is often lost under the banner of DRY. DRY
doesn’t mean “type as few characters as you can.” It means don’t
repeat functionality or knowledge within a system. IMO, multiple calls
to the same methods, but with different data, are NOT duplication in
this sense.

(I hit send too soon)

In the end, DRY exists to serve a higher master: maintainability. And
it is not terribly rare that the illusion of DRY (as explored in this
case) flies in the face of maintainability. In this case, the clarity
of the line number in the event of a failure wins for me.

Also, this is going to have to change when you decide that the
shopping list should raise an error when it receives “bagel.” Change
is fine, but to make that change is going to be more work and likely
leave things lopsided:

{
:milk => ‘milk’,
:coffee => ‘coffee’
}.each do |method, value|
@shopping_list.should_receive(method).and_return(value)
end

@shopping_list.should_receive(:bagel).and_raise(WeAreOutOfBagelsError)

To me, that is simply not as clear as this:

@shopping_list.should_receive(:milk).and_return(‘milk’)
@shopping_list.should_receive(:coffee).and_return(‘coffee’)
@shopping_list.should_receive(:bagel).and_raise(WeAreOutOfBagelsError)

FWIW,
David

:name => ‘The Battle for Blaze’
:people => 5000000
:activated => true)

Opinions?

A Hash is not ordered.
(but the 1st set of statements is)

Bye,
Kero.

On Dec 30, 2007 4:47 AM, Kero van Gelder [email protected] wrote:

@game.should_recieve_and_return(
:name => ‘The Battle for Blaze’
:people => 5000000
:activated => true)

Opinions?

A Hash is not ordered.
(but the 1st set of statements is)

I don’t know if this matters in this case. RSpec doesn’t enforce
strict-order mocking. Nor does Mocha. Hardmock is the only mocking
library in ruby that I know of that can do this,

I learn something everyday. Thanks

On Jan 2, 2008 5:20 PM, Zach D. [email protected] wrote:

RSpec doesn’t enforce strict-order mocking.

Sure it does, if you ask it to:
http://rspec.info/documentation/mocks/message_expectations.html

On 2 Jan 2008, at 22:09, David C. wrote:

On Jan 2, 2008 5:20 PM, Zach D. [email protected] wrote:

RSpec doesn’t enforce strict-order mocking.

Sure it does, if you ask it to:
http://rspec.info/documentation/mocks/message_expectations.html

Am I right, though, in thinking that you can’t enforce order between
two mocks? It would occasionally be nice to be able to say something
like:

master.should_receive(:start).and_then(slave).should_receive(:start)

On Jan 3, 2008 3:20 PM, Kerry B. [email protected] wrote:

Am I right, though, in thinking that you can’t enforce order between
two mocks? It would occasionally be nice to be able to say something
like:

master.should_receive(:start).and_then(slave).should_receive(:start)

Yes, you are correct. RSpec does not support this functionality.

On Jan 3, 2008 12:20 PM, Kerry B. [email protected] wrote:

Am I right, though, in thinking that you can’t enforce order between
two mocks? It would occasionally be nice to be able to say something
like:

master.should_receive(:start).and_then(slave).should_receive(:start)

I’d like to be proven wrong again, but I don’t think you can do this
with rspec. From running some examples in irb it looks like each mock
only verifies its own order. Hardmock does support this. Flexmock does
not that I am aware of, and Mocha most certainly does not.

Hardmock considers all expectations ordered across all mocks.
Hardmock does work with rspec too:
http://hardmock.rubyforge.org/doc/index.html