Greg Hauptmann
2008-Sep-05 14:08 UTC
[rspec-users] do I use mocking (vs fixtures) for methods that produce results based on non-trivial SQL queries
Hi, In cases where I have model methods that are generating data based on non-trivial SQL queries to a database (e.g. to pull together data required to plot an appropriate graph), does this really require a traditional fixture (i.e. pre-canned test data) as opposed to use of mocks? That is, the bulk of the method is really the SQL that is pull back (with multiple joins / selects etc) the data required. Testing to some extent should be focused around testing the SQL is producing what it should. How would one use rspec / mocha to solve this? i.e. in a normal testing sense you may need 5 to 10 rows before you can feel comfortable the SQL code is doing what it should.. Tks
Mark Wilden
2008-Sep-05 14:23 UTC
[rspec-users] do I use mocking (vs fixtures) for methods that produce results based on non-trivial SQL queries
On Fri, Sep 5, 2008 at 7:08 AM, Greg Hauptmann < greg.hauptmann.ruby at gmail.com> wrote:> Hi, > > In cases where I have model methods that are generating data based on > non-trivial SQL queries to a database (e.g. to pull together data > required to plot an appropriate graph), does this really require a > traditional fixture (i.e. pre-canned test data) as opposed to use of > mocks? >I don''t see how you could use mocks to test SQL. You need rows in the database to do this. I personally do not use fixtures because my model specs usually don''t use a "typical" data set. I''ll create my own data set for each type of spec, often using an object mother to create the valid network of objects. ///ark -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20080905/ab9394dc/attachment.html>
Scott Taylor
2008-Sep-05 14:37 UTC
[rspec-users] do I use mocking (vs fixtures) for methods that produce results based on non-trivial SQL queries
On Sep 5, 2008, at 10:08 AM, Greg Hauptmann wrote:> Hi, > > In cases where I have model methods that are generating data based on > non-trivial SQL queries to a database (e.g. to pull together data > required to plot an appropriate graph), does this really require a > traditional fixture (i.e. pre-canned test data) as opposed to use of > mocks?...> it should. How would one use rspec / mocha to solve this? i.e. in aYou tell me. Actually, there is no way, because stubs operate at a higher level on the call stack. Until rails treats *SQL* as an object (i.e., until there is a ruby SQL parser out there and rails uses it), stubbing will never be able to test real database activity. This is why rspec still recommends using real database rows in your tests - not because it''s an apriori requirement for testing against SQL data, but because it is currently the only way. Of course, the reason why people don''t like this answer is not really for the reason people like mocks otherwise (functional isolation). Instead, its because a large test suite hitting the database will become very slow over time. Just do the math: If one database test takes 0.2 sec (a realistic figure), then 5 will take 1 sec, at 1000 over 3 minutes, and at 2000 over 6 minutes. This is starting to get into "time for a coffee/cigarette/juggling what have you" breaks. So - either you end up very hyped up on coffee not doing much work, or you don''t run your test suite very often, which leads to legitimate bugs which can be solved. (At one point I had actually deployed code into production which had a serious bug. This all could have been avoided because the test suite *was failing*, but I had gotten into the habit of not running it because it was too expensive). I''ve been working hard on solving this issue by building a SQL parser in treetop, and hope anyone who is interested will join me (just let me know if you are interested and I''ll make the project publicly viewable on github). Scott
Pat Maddox
2008-Sep-05 14:40 UTC
[rspec-users] do I use mocking (vs fixtures) for methods that produce results based on non-trivial SQL queries
On Fri, Sep 5, 2008 at 7:23 AM, Mark Wilden <mark at mwilden.com> wrote:> On Fri, Sep 5, 2008 at 7:08 AM, Greg Hauptmann > <greg.hauptmann.ruby at gmail.com> wrote: >> >> Hi, >> >> In cases where I have model methods that are generating data based on >> non-trivial SQL queries to a database (e.g. to pull together data >> required to plot an appropriate graph), does this really require a >> traditional fixture (i.e. pre-canned test data) as opposed to use of >> mocks? > > I don''t see how you could use mocks to test SQL. You need rows in the > database to do this. I personally do not use fixtures because my model specs > usually don''t use a "typical" data set. I''ll create my own data set for each > type of spec, often using an object mother to create the valid network of > objects.+1
Pat Maddox
2008-Sep-05 14:55 UTC
[rspec-users] do I use mocking (vs fixtures) for methods that produce results based on non-trivial SQL queries
> time. Just do the math: If one database test takes 0.2 sec (a realistic > figure), then 5 will take 1 sec, at 1000 over 3 minutes, and at 2000 over 6 > minutes. This is starting to get into "time for a coffee/cigarette/juggling > what have you" breaks. So - either you end up very hyped up on coffee not > doing much work, or you don''t run your test suite very often, which leads to > legitimate bugs which can be solved. (At one point I had actually deployed > code into production which had a serious bug. This all could have been > avoided because the test suite *was failing*, but I had gotten into the > habit of not running it because it was too expensive).There''s a couple things you can do to help with this: * Split slow tests into another dir and run them separately from your fast suite. Keep rspactor on your fast suite and run the slow tests before checkin * Use a CI server> I''ve been working hard on solving this issue by building a SQL parser in > treetop, and hope anyone who is interested will join me (just let me know if > you are interested and I''ll make the project publicly viewable on github).http://github.com/nkallen/arel/tree/master might also be interesting to you. Pat
Scott Taylor
2008-Sep-05 15:09 UTC
[rspec-users] do I use mocking (vs fixtures) for methods that produce results based on non-trivial SQL queries
On Sep 5, 2008, at 10:55 AM, Pat Maddox wrote:>> time. Just do the math: If one database test takes 0.2 sec (a >> realistic >> figure), then 5 will take 1 sec, at 1000 over 3 minutes, and at >> 2000 over 6 >> minutes. This is starting to get into "time for a coffee/cigarette/ >> juggling >> what have you" breaks. So - either you end up very hyped up on >> coffee not >> doing much work, or you don''t run your test suite very often, which >> leads to >> legitimate bugs which can be solved. (At one point I had actually >> deployed >> code into production which had a serious bug. This all could have >> been >> avoided because the test suite *was failing*, but I had gotten into >> the >> habit of not running it because it was too expensive). > > There''s a couple things you can do to help with this: > > * Split slow tests into another dir and run them separately from your > fast suite. Keep rspactor on your fast suite and run the slow tests > before checkin > > * Use a CI server >Yes, most certainly. But the db tests ?still* aren''t cheap, meaning you''ll need to wait for the CI server to run them there is a failure, or wait before checking in. Also - have you found a CI server that is working with git?> >> I''ve been working hard on solving this issue by building a SQL >> parser in >> treetop, and hope anyone who is interested will join me (just let >> me know if >> you are interested and I''ll make the project publicly viewable on >> github). > > http://github.com/nkallen/arel/tree/master might also be interesting > to you.Hmm..Well, that''s interesting, although I think that project, like so many others, is *generating* SQL, not parsing it, correct? I''ve made my sql parser public, and here is is if anyone wants to take a gander (although it most certainly is still a work in progress): http://github.com/smtlaissezfaire/guillotine/tree/master Scott
Ben Mabey
2008-Sep-05 15:40 UTC
[rspec-users] do I use mocking (vs fixtures) for methods that produce results based on non-trivial SQL queries
Scott Taylor wrote:> > On Sep 5, 2008, at 10:55 AM, Pat Maddox wrote: > >>> time. Just do the math: If one database test takes 0.2 sec (a >>> realistic >>> figure), then 5 will take 1 sec, at 1000 over 3 minutes, and at 2000 >>> over 6 >>> minutes. This is starting to get into "time for a >>> coffee/cigarette/juggling >>> what have you" breaks. So - either you end up very hyped up on >>> coffee not >>> doing much work, or you don''t run your test suite very often, which >>> leads to >>> legitimate bugs which can be solved. (At one point I had actually >>> deployed >>> code into production which had a serious bug. This all could have been >>> avoided because the test suite *was failing*, but I had gotten into the >>> habit of not running it because it was too expensive). >> >> There''s a couple things you can do to help with this: >> >> * Split slow tests into another dir and run them separately from your >> fast suite. Keep rspactor on your fast suite and run the slow tests >> before checkin >> >> * Use a CI server >> > > Yes, most certainly. But the db tests ?still* aren''t cheap, meaning > you''ll need to wait for the CI server to run them there is a failure, > or wait before checking in. > > Also - have you found a CI server that is working with git?On github you can find forks of cc.rb with added git support. I have been using it like a charm for months.> >> >>> I''ve been working hard on solving this issue by building a SQL >>> parser in >>> treetop, and hope anyone who is interested will join me (just let me >>> know if >>> you are interested and I''ll make the project publicly viewable on >>> github). >>Thats cool. I was actually talking to our DBA about the possibility of this the other day. I think for the simple cases something like this would be great. I have been using the nulldb adapter will a lot of success recently but there are a few spots where just simple insert and select statements would go a long ways.>> http://github.com/nkallen/arel/tree/master might also be interesting >> to you. > > Hmm..Well, that''s interesting, although I think that project, like so > many others, is *generating* SQL, not parsing it, correct? > > I''ve made my sql parser public, and here is is if anyone wants to take > a gander (although it most certainly is still a work in progress): > > http://github.com/smtlaissezfaire/guillotine/tree/masterAwesome. I''ll for sure take a look at this.> > Scott > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-usersTo answer the original poster''s question.. I tend to isolate my SQL calls to single methods and don''t allow those methods to operate on the results. That way I can have a faster functional spec test that method individually with a smaller data set in the DB. I will then stub out the calls to that object#method in my specs where the interesting business logic uses that data to produce results. I then have an interaction test in form of a story that does more complex setup and testing of both methods and the DB in unison. My main motivation for this separation is for speed of my specs that are for my business logic. If what I have said doesn''t make sense I can given an example of what I mean. -Ben
Scott Taylor
2008-Sep-05 16:23 UTC
[rspec-users] do I use mocking (vs fixtures) for methods that produce results based on non-trivial SQL queries
On Sep 5, 2008, at 11:40 AM, Ben Mabey wrote:> Scott Taylor wrote: >> >> On Sep 5, 2008, at 10:55 AM, Pat Maddox wrote: >> >>>> time. Just do the math: If one database test takes 0.2 sec (a >>>> realistic >>>> figure), then 5 will take 1 sec, at 1000 over 3 minutes, and at >>>> 2000 >>>> over 6 >>>> minutes. This is starting to get into "time for a >>>> coffee/cigarette/juggling >>>> what have you" breaks. So - either you end up very hyped up on >>>> coffee not >>>> doing much work, or you don''t run your test suite very often, which >>>> leads to >>>> legitimate bugs which can be solved. (At one point I had actually >>>> deployed >>>> code into production which had a serious bug. This all could >>>> have been >>>> avoided because the test suite *was failing*, but I had gotten >>>> into the >>>> habit of not running it because it was too expensive). >>> >>> There''s a couple things you can do to help with this: >>> >>> * Split slow tests into another dir and run them separately from >>> your >>> fast suite. Keep rspactor on your fast suite and run the slow tests >>> before checkin >>> >>> * Use a CI server >>> >> >> Yes, most certainly. But the db tests ?still* aren''t cheap, meaning >> you''ll need to wait for the CI server to run them there is a failure, >> or wait before checking in. >> >> Also - have you found a CI server that is working with git? > > On github you can find forks of cc.rb with added git support. I have > been using it like a charm for months. >> >>> >>>> I''ve been working hard on solving this issue by building a SQL >>>> parser in >>>> treetop, and hope anyone who is interested will join me (just let >>>> me >>>> know if >>>> you are interested and I''ll make the project publicly viewable on >>>> github). >>> > Thats cool. I was actually talking to our DBA about the possibility > of > this the other day. I think for the simple cases something like this > would be great. I have been using the nulldb adapter will a lot of > success recently but there are a few spots where just simple insert > and > select statements would go a long ways. > >>> http://github.com/nkallen/arel/tree/master might also be interesting >>> to you. >> >> Hmm..Well, that''s interesting, although I think that project, like so >> many others, is *generating* SQL, not parsing it, correct? >> >> I''ve made my sql parser public, and here is is if anyone wants to >> take >> a gander (although it most certainly is still a work in progress): >> >> http://github.com/smtlaissezfaire/guillotine/tree/master > > Awesome. I''ll for sure take a look at this. >> >> Scott >> >> _______________________________________________ >> rspec-users mailing list >> rspec-users at rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users > > > To answer the original poster''s question.. I tend to isolate my SQL > calls to single methods and don''t allow those methods to operate on > the > results. That way I can have a faster functional spec test that > method > individually with a smaller data set in the DB. I will then stub out > the calls to that object#method in my specs where the interesting > business logic uses that data to produce results. I then have an > interaction test in form of a story that does more complex setup and > testing of both methods and the DB in unison. My main motivation for > this separation is for speed of my specs that are for my business > logic. If what I have said doesn''t make sense I can given an > example of > what I mean.Doesn''t this violate the rule of "never stub the method under test?" Scott
Ben Mabey
2008-Sep-05 17:01 UTC
[rspec-users] do I use mocking (vs fixtures) for methods that produce results based on non-trivial SQL queries
Scott Taylor wrote:> > On Sep 5, 2008, at 11:40 AM, Ben Mabey wrote: > >> Scott Taylor wrote: >>> >>> On Sep 5, 2008, at 10:55 AM, Pat Maddox wrote: >>> >>>>> time. Just do the math: If one database test takes 0.2 sec (a >>>>> realistic >>>>> figure), then 5 will take 1 sec, at 1000 over 3 minutes, and at 2000 >>>>> over 6 >>>>> minutes. This is starting to get into "time for a >>>>> coffee/cigarette/juggling >>>>> what have you" breaks. So - either you end up very hyped up on >>>>> coffee not >>>>> doing much work, or you don''t run your test suite very often, which >>>>> leads to >>>>> legitimate bugs which can be solved. (At one point I had actually >>>>> deployed >>>>> code into production which had a serious bug. This all could have >>>>> been >>>>> avoided because the test suite *was failing*, but I had gotten >>>>> into the >>>>> habit of not running it because it was too expensive). >>>> >>>> There''s a couple things you can do to help with this: >>>> >>>> * Split slow tests into another dir and run them separately from your >>>> fast suite. Keep rspactor on your fast suite and run the slow tests >>>> before checkin >>>> >>>> * Use a CI server >>>> >>> >>> Yes, most certainly. But the db tests ?still* aren''t cheap, meaning >>> you''ll need to wait for the CI server to run them there is a failure, >>> or wait before checking in. >>> >>> Also - have you found a CI server that is working with git? >> >> On github you can find forks of cc.rb with added git support. I have >> been using it like a charm for months. >>> >>>> >>>>> I''ve been working hard on solving this issue by building a SQL >>>>> parser in >>>>> treetop, and hope anyone who is interested will join me (just let me >>>>> know if >>>>> you are interested and I''ll make the project publicly viewable on >>>>> github). >>>> >> Thats cool. I was actually talking to our DBA about the possibility of >> this the other day. I think for the simple cases something like this >> would be great. I have been using the nulldb adapter will a lot of >> success recently but there are a few spots where just simple insert and >> select statements would go a long ways. >> >>>> http://github.com/nkallen/arel/tree/master might also be interesting >>>> to you. >>> >>> Hmm..Well, that''s interesting, although I think that project, like so >>> many others, is *generating* SQL, not parsing it, correct? >>> >>> I''ve made my sql parser public, and here is is if anyone wants to take >>> a gander (although it most certainly is still a work in progress): >>> >>> http://github.com/smtlaissezfaire/guillotine/tree/master >> >> Awesome. I''ll for sure take a look at this. >>> >>> Scott >>> >>> _______________________________________________ >>> rspec-users mailing list >>> rspec-users at rubyforge.org >>> http://rubyforge.org/mailman/listinfo/rspec-users >> >> >> To answer the original poster''s question.. I tend to isolate my SQL >> calls to single methods and don''t allow those methods to operate on the >> results. That way I can have a faster functional spec test that method >> individually with a smaller data set in the DB. I will then stub out >> the calls to that object#method in my specs where the interesting >> business logic uses that data to produce results. I then have an >> interaction test in form of a story that does more complex setup and >> testing of both methods and the DB in unison. My main motivation for >> this separation is for speed of my specs that are for my business >> logic. If what I have said doesn''t make sense I can given an example of >> what I mean. > > > Doesn''t this violate the rule of "never stub the method under test?" > > Scott >I probably didn''t explain that very well. Simple example: class WidgetRepository def self.some_method_that_isssues_complex_sql_to_find_the_data(*args) .... end end describe WidgetRepository, ".some_method_that_isssues_complex_sql_to_find_the_data" do #allow this one to hit the db it "should blah, blah..." do widget = create_widget ...(more setup)... WidgetRepository.some_method_that_isssues_complex_sql_to_find_the_data(*args).should == expected_results end ... end Then we have an object that uses the data: class WidgetYieldCalculator def calculate(widget, other_stuff) data WidgetRepository.some_method_that_isssues_complex_sql_to_find_the_data(some_args) ..operate on data.. return result end end Now to spec it, since the repository SQL call is all speced out, we can simply stub the call to WidgetRepository.some_method... and rely on the fact that the Respository will do it''s job: describe WidgetYieldCalculator, "#calculate" do it "should calculate the correct yield" do # given data = [...] widget = ... WidgetRepository.stub!(:some_method_that_isssues_complex_sql_to_find_the_data).and_return(data) #depending on the situation and spec an expectation is better than a stub # when result = WidgetYieldCalculator.new.calculate(widget, options) # then result.should == expected_results end end Sorry I don''t have more time to do a better example or explain it better. Basically, I was just advocating a separation of responsibilities: the data retrieval and operation on the data. This then allows you to mock your interface of the repository at a higher level. As I said, with the ActiveRecord pattern this kind of thinking seems a bit odd. In my rails projects the "repository" calls are usually class methods on an AR class. The big gain for this is that you can then test all your business logic in the WidgetYieldCalculator by varying the data which is stubbed. This reduces the number of DB calls considerably. You will need an integration spec for both of these parts to work together, and lately I have been starting with a story to drive the entire process. I wouldn''t got to such lengths on simple cases, but the current project I''m working on has driven me to do this in a number of places where lots of data and objects are involved. To answer your question more directly, I never stub a method of an object that I am testing.. I just stub the collaborator''s. Hope that clears it up a little, Ben
Matt Wynne
2008-Sep-05 19:17 UTC
[rspec-users] do I use mocking (vs fixtures) for methods that produce results based on non-trivial SQL queries
On 5 Sep 2008, at 16:40, Ben Mabey wrote:>> >> >> Also - have you found a CI server that is working with git? > > On github you can find forks of cc.rb with added git support. I have > been using it like a charm for months.In fact, the main thoughtworks github ccrb repo works with git now - we switched last week from the benburket fork and it seems fine. cheers, Matt ---- http://blog.mattwynne.net http://songkick.com In case you wondered: The opinions expressed in this email are my own and do not necessarily reflect the views of any former, current or future employers of mine.
Greg Hauptmann
2008-Sep-05 19:39 UTC
[rspec-users] do I use mocking (vs fixtures) for methods that produce results based on non-trivial SQL queries
Ben - I like your suggestion, thanks. I''ll start trying to structure some of my tests around this concept until there''s a better way. Mark - I''m curious to understand what you actually do re "I personally do not use fixtures because my model specs usually don''t use a "typical" data set. I''ll create my own data set for each type of spec, often using an object mother to create the valid network of objects." Did you just mean that at the start of a test you create test data in the database programmatically, as opposed to hard wiring it in a fixture? On Sat, Sep 6, 2008 at 3:01 AM, Ben Mabey <ben at benmabey.com> wrote:> Scott Taylor wrote: >> >> On Sep 5, 2008, at 11:40 AM, Ben Mabey wrote: >> >>> Scott Taylor wrote: >>>> >>>> On Sep 5, 2008, at 10:55 AM, Pat Maddox wrote: >>>> >>>>>> time. Just do the math: If one database test takes 0.2 sec (a >>>>>> realistic >>>>>> figure), then 5 will take 1 sec, at 1000 over 3 minutes, and at 2000 >>>>>> over 6 >>>>>> minutes. This is starting to get into "time for a >>>>>> coffee/cigarette/juggling >>>>>> what have you" breaks. So - either you end up very hyped up on >>>>>> coffee not >>>>>> doing much work, or you don''t run your test suite very often, which >>>>>> leads to >>>>>> legitimate bugs which can be solved. (At one point I had actually >>>>>> deployed >>>>>> code into production which had a serious bug. This all could have >>>>>> been >>>>>> avoided because the test suite *was failing*, but I had gotten >>>>>> into the >>>>>> habit of not running it because it was too expensive). >>>>> >>>>> There''s a couple things you can do to help with this: >>>>> >>>>> * Split slow tests into another dir and run them separately from your >>>>> fast suite. Keep rspactor on your fast suite and run the slow tests >>>>> before checkin >>>>> >>>>> * Use a CI server >>>>> >>>> >>>> Yes, most certainly. But the db tests ?still* aren''t cheap, meaning >>>> you''ll need to wait for the CI server to run them there is a failure, >>>> or wait before checking in. >>>> >>>> Also - have you found a CI server that is working with git? >>> >>> On github you can find forks of cc.rb with added git support. I have >>> been using it like a charm for months. >>>> >>>>> >>>>>> I''ve been working hard on solving this issue by building a SQL >>>>>> parser in >>>>>> treetop, and hope anyone who is interested will join me (just let me >>>>>> know if >>>>>> you are interested and I''ll make the project publicly viewable on >>>>>> github). >>>>> >>> Thats cool. I was actually talking to our DBA about the possibility of >>> this the other day. I think for the simple cases something like this >>> would be great. I have been using the nulldb adapter will a lot of >>> success recently but there are a few spots where just simple insert and >>> select statements would go a long ways. >>> >>>>> http://github.com/nkallen/arel/tree/master might also be interesting >>>>> to you. >>>> >>>> Hmm..Well, that''s interesting, although I think that project, like so >>>> many others, is *generating* SQL, not parsing it, correct? >>>> >>>> I''ve made my sql parser public, and here is is if anyone wants to take >>>> a gander (although it most certainly is still a work in progress): >>>> >>>> http://github.com/smtlaissezfaire/guillotine/tree/master >>> >>> Awesome. I''ll for sure take a look at this. >>>> >>>> Scott >>>> >>>> _______________________________________________ >>>> rspec-users mailing list >>>> rspec-users at rubyforge.org >>>> http://rubyforge.org/mailman/listinfo/rspec-users >>> >>> >>> To answer the original poster''s question.. I tend to isolate my SQL >>> calls to single methods and don''t allow those methods to operate on the >>> results. That way I can have a faster functional spec test that method >>> individually with a smaller data set in the DB. I will then stub out >>> the calls to that object#method in my specs where the interesting >>> business logic uses that data to produce results. I then have an >>> interaction test in form of a story that does more complex setup and >>> testing of both methods and the DB in unison. My main motivation for >>> this separation is for speed of my specs that are for my business >>> logic. If what I have said doesn''t make sense I can given an example of >>> what I mean. >> >> >> Doesn''t this violate the rule of "never stub the method under test?" >> >> Scott >> > > I probably didn''t explain that very well. Simple example: > > class WidgetRepository > def self.some_method_that_isssues_complex_sql_to_find_the_data(*args) > .... > end > end > > describe WidgetRepository, > ".some_method_that_isssues_complex_sql_to_find_the_data" do > #allow this one to hit the db > > it "should blah, blah..." do > widget = create_widget > ...(more setup)... > > WidgetRepository.some_method_that_isssues_complex_sql_to_find_the_data(*args).should > == expected_results > end > > ... > > end > > > Then we have an object that uses the data: > > class WidgetYieldCalculator > > def calculate(widget, other_stuff) > data > WidgetRepository.some_method_that_isssues_complex_sql_to_find_the_data(some_args) > ..operate on data.. > return result > end > end > > Now to spec it, since the repository SQL call is all speced out, we can > simply stub the call to WidgetRepository.some_method... and rely on the > fact that the Respository will do it''s job: > > describe WidgetYieldCalculator, "#calculate" do > it "should calculate the correct yield" do > # given > data = [...] > widget = ... > > WidgetRepository.stub!(:some_method_that_isssues_complex_sql_to_find_the_data).and_return(data) > > #depending on the situation and spec an expectation is > better than a stub > # when > result = WidgetYieldCalculator.new.calculate(widget, options) > # then > result.should == expected_results > end > > > end > > > > Sorry I don''t have more time to do a better example or explain it > better. Basically, I was just advocating a separation of > responsibilities: the data retrieval and operation on the data. This > then allows you to mock your interface of the repository at a higher > level. As I said, with the ActiveRecord pattern this kind of thinking > seems a bit odd. In my rails projects the "repository" calls are > usually class methods on an AR class. The big gain for this is that you > can then test all your business logic in the WidgetYieldCalculator by > varying the data which is stubbed. This reduces the number of DB calls > considerably. You will need an integration spec for both of these parts > to work together, and lately I have been starting with a story to drive > the entire process. I wouldn''t got to such lengths on simple cases, but > the current project I''m working on has driven me to do this in a number > of places where lots of data and objects are involved. > > To answer your question more directly, I never stub a method of an > object that I am testing.. I just stub the collaborator''s. > > Hope that clears it up a little, > Ben > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
Mark Wilden
2008-Sep-05 21:17 UTC
[rspec-users] do I use mocking (vs fixtures) for methods that produce results based on non-trivial SQL queries
On Fri, Sep 5, 2008 at 12:39 PM, Greg Hauptmann < greg.hauptmann.ruby at gmail.com> wrote:> Did you just mean that at the start of a test you create test data > in the database programmatically, as opposed to hard wiring it in a > fixture? >Yes, that''s right. Our code has a lot of support for creating networks of objects (e.g., you want to test a video, which requires some assets, a company, a site, maybe a reseller). Or you just mock out the other objects. The point is that you can get just the object(s) you want without the constraints of "one size fits all" data. In fact, fixtures can get in the way, which is why you''ll see Video.delete_all in a lot of our before(:each)''s (often accompanied by acerbic comments about "fixture bullshit.") As I''ve mentioned before, It''s been really great working with code from an RSpec master. The dividing line between his code and that of the other developers is fairly clear-cut. :) ///ark -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20080905/eaac66ff/attachment.html>
Pat Maddox
2008-Sep-06 03:19 UTC
[rspec-users] do I use mocking (vs fixtures) for methods that produce results based on non-trivial SQL queries
> In fact, fixtures can get in the way, which is why you''ll see > Video.delete_all in a lot of our before(:each)''s (often accompanied by > acerbic comments about "fixture bullshit.")Someone on your team has quite the potty mouth! :O ;) But seriously. Rails-style fixtures suck. You should be creating as much of the test data inline as possible (IMO), using helpers to build it for you. Pat
Scott Taylor
2008-Sep-06 03:39 UTC
[rspec-users] do I use mocking (vs fixtures) for methods that produce results based on non-trivial SQL queries
On Sep 5, 2008, at 3:39 PM, Greg Hauptmann wrote:> Ben - I like your suggestion, thanks. I''ll start trying to structure > some of my tests around this concept until there''s a better way. > > Mark - I''m curious to understand what you actually do re "I personally > do not use fixtures because my model specs usually don''t use a > "typical" data set. I''ll create my own data set for each type of spec, > often using an object mother to create the valid network of objects." > Did you just mean that at the start of a test you create test data > in the database programmatically, as opposed to hard wiring it in a > fixture?You might want to check out Dan Manges'' post from a while back: http://www.dcmanges.com/blog/38 There are a ton of plugins out there that implement the idea. I wrote FixtureReplacement (http://replacefixtures.rubyforge.org/) after this idea, but there are actually a ton of them out there that do more or less the same thing - ObjectDaddy, factory_girl). Scott