From bkocik at gmail.com Mon Oct 20 11:14:17 2008 From: bkocik at gmail.com (Bill Kocik) Date: Mon, 20 Oct 2008 11:14:17 -0400 Subject: [mocha-developer] Stubbing objects and calling to_json on them errors (circular reference) Message-ID: <1A4AE300-95AF-4F7A-A099-65871DD07832@gmail.com> My apologies if there's a user list I should be posting this to. I didn't find one. Suppose you have a controller action like this: def do_something @something = Something.find(:first) @something.do_whatever render :json => @something.to_json end A test might be this: context "when do_something is called" do setup do @something = Something.new() Something.expects(:find).returns(@something) @something.stubs(:do_whatever) get :do_something end should_respond_with :success end Because I stubbed a method on my @something object (and this also happens with expects()), I get this: 1) Error: test: when do_something is called should respond with success. (SomethingControllerTest): ActiveSupport::JSON::CircularReferenceError: object references itself If I print out the object @something, I see that it contains an @mocha attribute that references the containing object, which is the cause of to_json's heartburn and the error. But that @mocha attribute is not present if I never call stubs() or expects() on the object that's going to be converted to JSON, and I do not get the error in that case. Can anyone show me what I'm doing wrong, or is this actually a known issue? -- Bill Kocik From johnwilger at gmail.com Mon Oct 20 14:01:57 2008 From: johnwilger at gmail.com (John Wilger) Date: Mon, 20 Oct 2008 11:01:57 -0700 Subject: [mocha-developer] Stubbing objects and calling to_json on them errors (circular reference) In-Reply-To: <1A4AE300-95AF-4F7A-A099-65871DD07832@gmail.com> References: <1A4AE300-95AF-4F7A-A099-65871DD07832@gmail.com> Message-ID: On Oct 20, 2008, at 8:14 AM, Bill Kocik wrote: > Suppose you have a controller action like this: > > def do_something > @something = Something.find(:first) > @something.do_whatever > render :json => @something.to_json > end > > A test might be this: > > context "when do_something is called" do > setup do > @something = Something.new() > Something.expects(:find).returns(@something) > @something.stubs(:do_whatever) > get :do_something > end > should_respond_with :success > end > > Because I stubbed a method on my @something object (and this also > happens with expects()), I get this: > > 1) Error: > test: when do_something is called should respond with success. > (SomethingControllerTest): > ActiveSupport::JSON::CircularReferenceError: object references itself Hi Bill, I would suggest not using an actual instance of Something at all. You are testing SomethingController, not Something?and you are already using mocking/stubbing?so why not just have: context "when do_something is called" do setup do something = stub_everything Something.stubs(:find).returns(something) get :do_something end should_respond_with :success end -- Regards, John Wilger From bkocik at gmail.com Mon Oct 20 15:10:05 2008 From: bkocik at gmail.com (Bill Kocik) Date: Mon, 20 Oct 2008 15:10:05 -0400 Subject: [mocha-developer] Stubbing objects and calling to_json on them errors (circular reference) In-Reply-To: References: <1A4AE300-95AF-4F7A-A099-65871DD07832@gmail.com> Message-ID: <62EE37E7-2910-4589-9553-91B2D2332A5D@gmail.com> On 20 Oct, 2008, at 2:01 PM, John Wilger wrote: > Hi Bill, > > I would suggest not using an actual instance of Something at all. > You are testing SomethingController, not Something I'm right there with ya, John. Sadly the situation I'm in is that I've just joined this project, and it's kind of a mess. In some cases I can mock the object (and I do), but in others there are so many calls to the object, and then calls to objects that come back from those calls, that stubbing all that stuff out is a little bit prohibitive. It's in these situations that I opt to create a genuine object. Our first step in the cleanup effort is to try to increase our test coverage to a level we're comfortable with, so for now I'm stuck with writing less- than-ideal tests for less-than-ideal code. I think a work-around I can use for now (until we can clean all of this up) is to stub the to_json method. -- Bill Kocik From johnwilger at gmail.com Mon Oct 20 15:46:33 2008 From: johnwilger at gmail.com (John Wilger) Date: Mon, 20 Oct 2008 12:46:33 -0700 Subject: [mocha-developer] Stubbing objects and calling to_json on them errors (circular reference) In-Reply-To: <62EE37E7-2910-4589-9553-91B2D2332A5D@gmail.com> References: <1A4AE300-95AF-4F7A-A099-65871DD07832@gmail.com> <62EE37E7-2910-4589-9553-91B2D2332A5D@gmail.com> Message-ID: <20EDDE95-0A45-41A1-8933-65375D034997@gmail.com> On Oct 20, 2008, at 12:10 PM, Bill Kocik wrote: > > I'm right there with ya, John. Sadly the situation I'm in is that > I've just joined this project, and it's kind of a mess. In some > cases I can mock the object (and I do), but in others there are so > many calls to the object, and then calls to objects that come back > from those calls, that stubbing all that stuff out is a little bit > prohibitive. It's in these situations that I opt to create a genuine > object. Our first step in the cleanup effort is to try to increase > our test coverage to a level we're comfortable with, so for now I'm > stuck with writing less-than-ideal tests for less-than-ideal code. Using `stub_everything` as opposed to just `stub` can alleviate that to some degree, however the one thing I don't like about Mocha is `stub_everything` returns nil for all calls. If it instead returned `self` by default, then it would work better for this kind of situation. (If anyone knows that there /is/ a way to cause Mocha to behave this way, please speak up!) -- Regards, John Wilger From duelin.markers at gmail.com Fri Oct 24 08:49:09 2008 From: duelin.markers at gmail.com (John D. Hume) Date: Fri, 24 Oct 2008 08:49:09 -0400 Subject: [mocha-developer] Stubbing objects and calling to_json on them errors (circular reference) In-Reply-To: <62EE37E7-2910-4589-9553-91B2D2332A5D@gmail.com> References: <1A4AE300-95AF-4F7A-A099-65871DD07832@gmail.com> <62EE37E7-2910-4589-9553-91B2D2332A5D@gmail.com> Message-ID: On Mon, Oct 20, 2008 at 3:10 PM, Bill Kocik wrote: > Our first step in the cleanup effort is to > try to increase our test coverage to a level we're comfortable with, so for > now I'm stuck with writing less-than-ideal tests for less-than-ideal code. Bill, I realize it's been a few days and apologize for the late response, but I just saw this. I hate to be the guy on the mailing list saying "you shouldn't be trying to do what you're trying to do," but that's sort of where I'm headed. I hope it's helpful anyway. When adopting a codebase that wasn't developed test-driven, I'd strongly recommend focusing on Rails-style functional tests rather than introducing mock-based testing of the current design. The biggest downside to mocking is that it ties you to certain interactions between objects. When you're using it to determine what those interactions should be, that's ok. When you already know you're not happy with the way those interactions work and intend to clean them up, what you really need is tests that give you a safety net to enable refactoring (a green bar that you can keep green as you improve the design). Mock-based tests aren't likely to give you that. Rather they're probably going to mean that as you skinny down your controllers, you'll have to change everything in at least two places instead of just one, and meanwhile the suite won't tell you whether things are still working. Mock-based tests are a useful design tool, and can (in some cases) be useful documentation of design, but they don't usually make for a good regression suite. All three of those are important when developing from scratch. But when taking on legacy code whose design you intend to change, the first two goals are off the table. The third is better served with higher-level tests. It's definitely worth your time to read the 12-page version of Michael Feathers' Working Effectively With Legacy Code. www.objectmentor.com/resources/articles/WorkingEffectivelyWithLegacyCode.pdf I hope that wasn't too obnoxious. -hume. -- http://elhumidor.blogspot.com/ From bkocik at gmail.com Fri Oct 24 09:26:38 2008 From: bkocik at gmail.com (Bill Kocik) Date: Fri, 24 Oct 2008 09:26:38 -0400 Subject: [mocha-developer] Stubbing objects and calling to_json on them errors (circular reference) In-Reply-To: References: <1A4AE300-95AF-4F7A-A099-65871DD07832@gmail.com> <62EE37E7-2910-4589-9553-91B2D2332A5D@gmail.com> Message-ID: Please don't apologize - this is probably the best, most well- delivered advice I've ever received from a mailing list, and I greatly appreciate it. I've actually sort of thought the same thing; what I'm doing now is testing implementation rather than results, and while I knew it wasn't what I should be doing I wasn't quite sure what that thing I should be doing was. Thanks very much for taking the time to spell some of this out for me. You've taught me something, which I'm grateful for, and I'm going to share your advice with my direct manager and suggest that we consider a change in testing focus. On 24 Oct, 2008, at 8:49 AM, John D. Hume wrote: > On Mon, Oct 20, 2008 at 3:10 PM, Bill Kocik wrote: >> Our first step in the cleanup effort is to >> try to increase our test coverage to a level we're comfortable >> with, so for >> now I'm stuck with writing less-than-ideal tests for less-than- >> ideal code. > > Bill, > I realize it's been a few days and apologize for the late response, > but I just saw this. I hate to be the guy on the mailing list saying > "you shouldn't be trying to do what you're trying to do," but that's > sort of where I'm headed. I hope it's helpful anyway. > > When adopting a codebase that wasn't developed test-driven, I'd > strongly recommend focusing on Rails-style functional tests rather > than introducing mock-based testing of the current design. The biggest > downside to mocking is that it ties you to certain interactions > between objects. When you're using it to determine what those > interactions should be, that's ok. When you already know you're not > happy with the way those interactions work and intend to clean them > up, what you really need is tests that give you a safety net to enable > refactoring (a green bar that you can keep green as you improve the > design). Mock-based tests aren't likely to give you that. Rather > they're probably going to mean that as you skinny down your > controllers, you'll have to change everything in at least two places > instead of just one, and meanwhile the suite won't tell you whether > things are still working. > > Mock-based tests are a useful design tool, and can (in some cases) be > useful documentation of design, but they don't usually make for a good > regression suite. All three of those are important when developing > from scratch. But when taking on legacy code whose design you intend > to change, the first two goals are off the table. The third is better > served with higher-level tests. > > It's definitely worth your time to read the 12-page version of Michael > Feathers' Working Effectively With Legacy Code. > www.objectmentor.com/resources/articles/WorkingEffectivelyWithLegacyCode.pdf > > I hope that wasn't too obnoxious. > -hume. > > -- > http://elhumidor.blogspot.com/ > _______________________________________________ > mocha-developer mailing list > mocha-developer at rubyforge.org > http://rubyforge.org/mailman/listinfo/mocha-developer -- Bill Kocik From jamesmead44 at gmail.com Sun Oct 26 15:09:54 2008 From: jamesmead44 at gmail.com (James Mead) Date: Sun, 26 Oct 2008 19:09:54 +0000 Subject: [mocha-developer] Stubbing objects and calling to_json on them errors (circular reference) In-Reply-To: <1A4AE300-95AF-4F7A-A099-65871DD07832@gmail.com> References: <1A4AE300-95AF-4F7A-A099-65871DD07832@gmail.com> Message-ID: <1db558f00810261209m4d1f22adu56732b138df86b2c@mail.gmail.com> 2008/10/20 Bill Kocik > > My apologies if there's a user list I should be posting this to. I didn't > find one. No worries. This list serves as both user & developer list. > Suppose you have a controller action like this: > > def do_something > @something = Something.find(:first) > @something.do_whatever > render :json => @something.to_json > end > > A test might be this: > > context "when do_something is called" do > setup do > @something = Something.new() > Something.expects(:find).returns(@something) > @something.stubs(:do_whatever) > get :do_something > end > should_respond_with :success > end > > Because I stubbed a method on my @something object (and this also happens > with expects()), I get this: > > 1) Error: > test: when do_something is called should respond with success. > (SomethingControllerTest): > ActiveSupport::JSON::CircularReferenceError: object references itself > > If I print out the object @something, I see that it contains an @mocha > attribute that references the containing object, which is the cause of > to_json's heartburn and the error. But that @mocha attribute is not present > if I never call stubs() or expects() on the object that's going to be > converted to JSON, and I do not get the error in that case. Can anyone show > me what I'm doing wrong, or is this actually a known issue? > > -- > Bill Kocik > This sounds like a bug. I'm going to add a bug report to track this [1]. Thanks for letting us know about it. -- James. http://blog.floehopper.org [1] http://rubyforge.org/tracker/index.php?group_id=1917&atid=7477 From jamesmead44 at gmail.com Sun Oct 26 15:16:58 2008 From: jamesmead44 at gmail.com (James Mead) Date: Sun, 26 Oct 2008 19:16:58 +0000 Subject: [mocha-developer] Stubbing objects and calling to_json on them errors (circular reference) In-Reply-To: <20EDDE95-0A45-41A1-8933-65375D034997@gmail.com> References: <1A4AE300-95AF-4F7A-A099-65871DD07832@gmail.com> <62EE37E7-2910-4589-9553-91B2D2332A5D@gmail.com> <20EDDE95-0A45-41A1-8933-65375D034997@gmail.com> Message-ID: <1db558f00810261216g20085a6euad57b81534b9be36@mail.gmail.com> 2008/10/20 John Wilger > Using `stub_everything` as opposed to just `stub` can alleviate that to > some degree, however the one thing I don't like about Mocha is > `stub_everything` returns nil for all calls. If it instead returned `self` > by default, then it would work better for this kind of situation. (If anyone > knows that there /is/ a way to cause Mocha to behave this way, please speak > up!) > Hi John, Thanks for your message. There isn't currently a way to do this. I'm not convinced that always returning "self" would be sensible, but I can see the case for having control over the default return value. I've added a feature request [1] to track this and I'll have a think about how the API would work. In the meantime if you have any ideas, please let me know. Thanks. -- James. http://blog.floehopper.org [1] http://rubyforge.org/tracker/index.php?func=detail&aid=22564&group_id=1917&atid=7480 From jamesmead44 at gmail.com Sun Oct 26 15:22:14 2008 From: jamesmead44 at gmail.com (James Mead) Date: Sun, 26 Oct 2008 19:22:14 +0000 Subject: [mocha-developer] Stubbing objects and calling to_json on them errors (circular reference) In-Reply-To: References: <1A4AE300-95AF-4F7A-A099-65871DD07832@gmail.com> <62EE37E7-2910-4589-9553-91B2D2332A5D@gmail.com> Message-ID: <1db558f00810261222w70f5e69ved9be05ab1b3d1e5@mail.gmail.com> 2008/10/24 John D. Hume > Bill, > I realize it's been a few days and apologize for the late response, > but I just saw this. I hate to be the guy on the mailing list saying > "you shouldn't be trying to do what you're trying to do," but that's > sort of where I'm headed. I hope it's helpful anyway. > > When adopting a codebase that wasn't developed test-driven, I'd > strongly recommend focusing on Rails-style functional tests rather > than introducing mock-based testing of the current design. The biggest > downside to mocking is that it ties you to certain interactions > between objects. When you're using it to determine what those > interactions should be, that's ok. When you already know you're not > happy with the way those interactions work and intend to clean them > up, what you really need is tests that give you a safety net to enable > refactoring (a green bar that you can keep green as you improve the > design). Mock-based tests aren't likely to give you that. Rather > they're probably going to mean that as you skinny down your > controllers, you'll have to change everything in at least two places > instead of just one, and meanwhile the suite won't tell you whether > things are still working. > > Mock-based tests are a useful design tool, and can (in some cases) be > useful documentation of design, but they don't usually make for a good > regression suite. All three of those are important when developing > from scratch. But when taking on legacy code whose design you intend > to change, the first two goals are off the table. The third is better > served with higher-level tests. > > It's definitely worth your time to read the 12-page version of Michael > Feathers' Working Effectively With Legacy Code. > > www.objectmentor.com/resources/articles/WorkingEffectivelyWithLegacyCode.pdf > Hi John, Thanks for that excellent constructive response. Sorry I haven't been active on the list for a while - I really appreciate you taking the time to help Bill. Thanks also for the pointer to that shortened version of Michael Feathers' book. -- James. http://blog.floehopper.org From jay at jayfields.com Sun Oct 26 17:38:51 2008 From: jay at jayfields.com (Jay Fields) Date: Sun, 26 Oct 2008 16:38:51 -0500 Subject: [mocha-developer] stub_everything returning self (was: something else) In-Reply-To: <1db558f00810261216g20085a6euad57b81534b9be36@mail.gmail.com> References: <1A4AE300-95AF-4F7A-A099-65871DD07832@gmail.com> <62EE37E7-2910-4589-9553-91B2D2332A5D@gmail.com> <20EDDE95-0A45-41A1-8933-65375D034997@gmail.com> <1db558f00810261216g20085a6euad57b81534b9be36@mail.gmail.com> Message-ID: I'm not sold on stub_everything returning self. Generally you only want that kind of behavior if you violate the law of demeter. There are cases where this is desirable, but they are few and far between in my experience. Changing mocha to help you violate the law of demeter seems like a bad idea. Although, I guess you could argue that people should be given all the rope they want. Cheers, Jay On Oct 26, 2008, at 2:16 PM, James Mead wrote: > 2008/10/20 John Wilger > >> Using `stub_everything` as opposed to just `stub` can alleviate >> that to >> some degree, however the one thing I don't like about Mocha is >> `stub_everything` returns nil for all calls. If it instead returned >> `self` >> by default, then it would work better for this kind of situation. >> (If anyone >> knows that there /is/ a way to cause Mocha to behave this way, >> please speak >> up!) >> > > Hi John, > > Thanks for your message. There isn't currently a way to do this. I'm > not > convinced that always returning "self" would be sensible, but I can > see the > case for having control over the default return value. I've added a > feature > request [1] to track this and I'll have a think about how the API > would > work. In the meantime if you have any ideas, please let me know. > > Thanks. > -- > James. > http://blog.floehopper.org > > [1] > http://rubyforge.org/tracker/index.php?func=detail&aid=22564&group_id=1917&atid=7480 > _______________________________________________ > mocha-developer mailing list > mocha-developer at rubyforge.org > http://rubyforge.org/mailman/listinfo/mocha-developer From johnwilger at gmail.com Sun Oct 26 21:22:57 2008 From: johnwilger at gmail.com (John Wilger) Date: Sun, 26 Oct 2008 18:22:57 -0700 Subject: [mocha-developer] stub_everything returning self (was: something else) In-Reply-To: References: <1A4AE300-95AF-4F7A-A099-65871DD07832@gmail.com> <62EE37E7-2910-4589-9553-91B2D2332A5D@gmail.com> <20EDDE95-0A45-41A1-8933-65375D034997@gmail.com> <1db558f00810261216g20085a6euad57b81534b9be36@mail.gmail.com> Message-ID: <70D9E647-A83F-4B6E-970C-AA12ACDCDA68@gmail.com> Jay, Where it comes in handy is when you have to work with poorly written dependencies that violate LoD and you don't have a good way to either replace them or adapt them. It definitely should /not/ be the default behavior to return self, but the option to do so would be helpful in some cicumstances. -- Regards, John Wilger On Oct 26, 2008, at 2:38 PM, Jay Fields wrote: > I'm not sold on stub_everything returning self. Generally you only > want that kind of behavior if you violate the law of demeter. There > are cases where this is desirable, but they are few and far between > in my experience. Changing mocha to help you violate the law of > demeter seems like a bad idea. Although, I guess you could argue > that people should be given all the rope they want. > > Cheers, Jay > > > On Oct 26, 2008, at 2:16 PM, James Mead wrote: > >> 2008/10/20 John Wilger >> >>> Using `stub_everything` as opposed to just `stub` can alleviate >>> that to >>> some degree, however the one thing I don't like about Mocha is >>> `stub_everything` returns nil for all calls. If it instead >>> returned `self` >>> by default, then it would work better for this kind of situation. >>> (If anyone >>> knows that there /is/ a way to cause Mocha to behave this way, >>> please speak >>> up!) >>> >> >> Hi John, >> >> Thanks for your message. There isn't currently a way to do this. >> I'm not >> convinced that always returning "self" would be sensible, but I can >> see the >> case for having control over the default return value. I've added a >> feature >> request [1] to track this and I'll have a think about how the API >> would >> work. In the meantime if you have any ideas, please let me know. >> >> Thanks. >> -- >> James. >> http://blog.floehopper.org >> >> [1] >> http://rubyforge.org/tracker/index.php?func=detail&aid=22564&group_id=1917&atid=7480 >> _______________________________________________ >> mocha-developer mailing list >> mocha-developer at rubyforge.org >> http://rubyforge.org/mailman/listinfo/mocha-developer > > _______________________________________________ > mocha-developer mailing list > mocha-developer at rubyforge.org > http://rubyforge.org/mailman/listinfo/mocha-developer