Greg Hauptmann
2008-Oct-05 11:26 UTC
[rspec-users] would I stub an existing class method out or use fixtures in this scenario?
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
Matt Wynne
2008-Oct-05 20:47 UTC
[rspec-users] would I stub an existing class method out or use fixtures in this scenario?
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 associatedIs 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.
Matt Wynne
2008-Oct-05 20:52 UTC
[rspec-users] would I stub an existing class method out or use fixtures in this scenario?
On 5 Oct 2008, at 12:26, Greg Hauptmann wrote:> 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?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?
Scott Taylor
2008-Oct-05 20:56 UTC
[rspec-users] would I stub an existing class method out or use fixtures in this scenario?
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/tickets/28-6791-stub-return-values-for-all-instances-of-a-class#ticket-28-5) , which wasn''t accepted into core for asthetic reasons. Feel free to revise it ;) Scott
Matt Wynne
2008-Oct-05 21:04 UTC
[rspec-users] would I stub an existing class method out or use fixtures in this scenario?
On 5 Oct 2008, at 21:56, Scott Taylor wrote:> > 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.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?
Scott Taylor
2008-Oct-05 21:29 UTC
[rspec-users] would I stub an existing class method out or use fixtures in this scenario?
On Oct 5, 2008, at 5:04 PM, Matt Wynne wrote:> On 5 Oct 2008, at 21:56, Scott Taylor wrote: > >> >> 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. > > 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?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 >>>> associatedNotice "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
Greg Hauptmann
2008-Oct-06 04:26 UTC
[rspec-users] would I stub an existing class method out or use fixtures in this scenario?
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
Mark Wilden
2008-Oct-06 17:50 UTC
[rspec-users] would I stub an existing class method out or use fixtures in this scenario?
On Sun, Oct 5, 2008 at 9:26 PM, Greg Hauptmann < greg.hauptmann.ruby at 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 -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20081006/06bead3b/attachment.html>