Forum: RSpec would I stub an existing class method out or use fixtures in this scenario?

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
D5df9fcd7ef4c3c937435d7d6adeab2a?d=identicon&s=25 Greg Hauptmann (Guest)
on 2008-10-05 13:26
(Received via mailing list)
Hi,

Would the BDD experts recommend I either (a) use fixtures for data or
(b) stub out existing class methods for such a scenario?

Scenario = Working on a "populate for future transactions" method &
testing this.  It generates "transactions" table rows as part of the
test.  To do this it (a) requires BankAccount table row entries to be
in place to ensure foreign key constraints allow new "transaction" to
be added, i.e. with a bank_account_id which exists, and (b) ability to
call the BankAccount class method "balance?(date)".

Discussion = I've set things up with dynamic fixture type data using
Ruby code (in the before(:each) do), however I was wondering whether
in fact I should not be having to create such data (i.e. bank_account
rows, when the real code under test is generating new "transaction"
rows) but rather be "stubbing" out the existing methods on the
BankAccount model (e.g.
BankAccount.any_instance.stubs(:balance?).returns(<as required>)).

Do people normal use the "any_instance.stubs" approach to stub out
existing classes already developed, as a means to minimize associated
test data that may have to be put in place to allow the test to work?
Any other comments/suggestions re best practice here?

Tks
Cdf378de2284d8acf137122e541caa28?d=identicon&s=25 Matt Wynne (mattwynne)
on 2008-10-06 01:11
(Received via mailing list)
On 5 Oct 2008, at 12:26, Greg Hauptmann wrote:
> BankAccount.any_instance.stubs(:balance?).returns(<as required>)).
>
> Do people normal use the "any_instance.stubs" approach to stub out
> existing classes already developed, as a means to minimize associated

Is this any_instance thing in the rspec mocking framework now? I
vaguely remember wanting this a few weeks ago and it was only in mocha
or another of the competing mocking frameworks.
944f769c99deff7aa8bc3b5b93830b7a?d=identicon&s=25 Scott Taylor (Guest)
on 2008-10-06 01:45
(Received via mailing list)
On Oct 5, 2008, at 4:47 PM, Matt Wynne wrote:

> On 5 Oct 2008, at 12:26, Greg Hauptmann wrote:
>> BankAccount.any_instance.stubs(:balance?).returns(<as required>)).
>>
>> Do people normal use the "any_instance.stubs" approach to stub out
>> existing classes already developed, as a means to minimize associated
>
> Is this any_instance thing in the rspec mocking framework now? I
> vaguely remember wanting this a few weeks ago and it was only in
> mocha or another of the competing mocking frameworks.

No, it isn't.  Most consider it a code smell, which is why it hasn't
been high on the priority list.

I submitted a patch a while back for this (see:
http://rspec.lighthouseapp.com/projects/5645/ticke...)
, which wasn't accepted into core for asthetic reasons.  Feel free to
revise it ;)

Scott
Cdf378de2284d8acf137122e541caa28?d=identicon&s=25 Matt Wynne (mattwynne)
on 2008-10-06 02:01
(Received via mailing list)
On 5 Oct 2008, at 21:56, Scott Taylor wrote:

>> Is this any_instance thing in the rspec mocking framework now? I
>> vaguely remember wanting this a few weeks ago and it was only in
>> mocha or another of the competing mocking frameworks.
>
> No, it isn't.  Most consider it a code smell, which is why it hasn't
> been high on the priority list.

So does this suggest there's something wrong with Greg's design? Does
he maybe need to sprout a new class to handle the generation of the
transactions, and pass that a specific BankAccount instance?
944f769c99deff7aa8bc3b5b93830b7a?d=identicon&s=25 Scott Taylor (Guest)
on 2008-10-06 02:12
(Received via mailing list)
On Oct 5, 2008, at 5:04 PM, Matt Wynne wrote:

>>>> associated
> the transactions, and pass that a specific BankAccount instance?
Well, Look at this comment previously written in the thread:

>>>> Do people normal use the "any_instance.stubs" approach to stub out
>>>> existing classes already developed, as a means to minimize
>>>> associated

Notice "existing classes" - this usually means classes that haven't
been developed test first.  if they had been developed test first,
they'd probably be trivial to test with.

Scott
Cdf378de2284d8acf137122e541caa28?d=identicon&s=25 Matt Wynne (mattwynne)
on 2008-10-06 03:08
(Received via mailing list)
On 5 Oct 2008, at 12:26, Greg Hauptmann wrote:

> call the BankAccount class method "balance?(date)".
> existing classes already developed, as a means to minimize associated
> test data that may have to be put in place to allow the test to work?
> Any other comments/suggestions re best practice here?

I think you should be able to do this with mocks, but it's not going
to be easy. Are you using ActiveRecord?

I might be being thick, but I'm not really clear what the desired
behaviour is from the question. Can you maybe post a spec --format
specdoc of the relevant specs?
D5df9fcd7ef4c3c937435d7d6adeab2a?d=identicon&s=25 Greg Hauptmann (Guest)
on 2008-10-06 06:26
(Received via mailing list)
Hi guys,

I'll try to put some clarifying comments here re my question:

(a) "any_instance.stubs" - this already exists in Mocha
(http://mocha.rubyforge.org/classes/Class.html#M000001)

(b) where I had "do people normal use the "any_instance.stubs"
approach to stub out existing classes already developed" - this should
have read for "an existing method in an existing class".   In my case
I had a method in the BankAccount model which requires "bankaccounts"
table rows to be populated, so I was asking re stubbing this out.

(c) as a quick overview of the key elements of my question, I have:

* "recurrings" table - has details of recurring items (e.g. food,
$200, every week). Has foreign key to BankAccount re where the expense
is likely to turn up against.
* "transactions" table - has actual plus future projected
transactions. Has BankAccount foreign key.
* "bank_accounts" table - ID and name for each bank account
* BankAccount model - Has method "balance?(date=Today.now.to_date)
which gets balance for that bank account for that date (by looking at
the transactions table)
* "populate_projections" method - this is what I want to test. It
basically:
  - reads input from "recurrings" table
  - creates "transactions" table rows
  - during the process calls BankAccount.balance? method

So overall I'm pondering how to test my "populate_projections" method
in a manner that minimises the amount of dynamically generated
fixtures I have to create (currently I create recurring items &
bank_accounts), and also the reliance on the BankAccount.balance?
method (and it's correct operation).  My specific question was about
how to stub out the already existing BankAccount.balance? method using
"any_instance.stubs".

Any feedback welcome on what the best practice would be here.

Cheers
Greg
48641c4be1fbe167929fb16c9fd94990?d=identicon&s=25 Mark Wilden (Guest)
on 2008-10-06 19:52
(Received via mailing list)
On Sun, Oct 5, 2008 at 9:26 PM, Greg Hauptmann <
greg.hauptmann.ruby@gmail.com> wrote:

> So overall I'm pondering how to test my "populate_projections" method
> in a manner that minimises the amount of dynamically generated
> fixtures I have to create (currently I create recurring items &
> bank_accounts), and also the reliance on the BankAccount.balance?
> method (and it's correct operation).  My specific question was about
> how to stub out the already existing BankAccount.balance? method using
> "any_instance.stubs".
>

In general, I do something like

bank_account = mock_model(BankAccount, :balance => 12)
BankAccount.stub!(:find).with(bank_account.id).and_return bank_account

Is that what you're talking about? As opposed to

bank_account = BankAcount.create!
Transaction.create!(:back_account_id => bank_account.id, :amount => 12)

Are you asking which one is better, or am I totally off on the wrong
track?
:) Otherwise, I'd pick the first approach, because it's faster.

///ark
This topic is locked and can not be replied to.