tag:blogger.com,1999:blog-3483689298596906177.post8946144584520595518..comments2023-03-19T13:38:03.728+01:00Comments on Codecaster: BDD, isolation, integrationPapipohttp://www.blogger.com/profile/10673361479709852302noreply@blogger.comBlogger20125tag:blogger.com,1999:blog-3483689298596906177.post-12093637570813659952011-01-24T19:16:02.701+01:002011-01-24T19:16:02.701+01:00Good luck getting people behind this one. Though ...Good luck getting people behind this one. Though you make some VERY fascinating points, youre going to have to do more than bring up a few things that may be different than what weve already heard. What are trying to say here? What do you want us to think? It seems like you cant really get behind a unique thought. Anyway, thats just my opinion.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-3483689298596906177.post-24656781467347925502011-01-24T16:24:22.795+01:002011-01-24T16:24:22.795+01:00Truly inspiring, touching and moving true stories....Truly inspiring, touching and moving true stories. Every human being is a bunch of different life stories. Let us keep knowing and learning.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-3483689298596906177.post-40567639072966939382011-01-24T06:49:55.094+01:002011-01-24T06:49:55.094+01:00It was a really nice thought! Just wanna say thank...It was a really nice thought! Just wanna say thank you for the selective information you have diffused. Just continue writing this kind of post. I will be your loyal reader. Gives Thanks over again.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-3483689298596906177.post-10161503068801720452011-01-23T10:59:18.855+01:002011-01-23T10:59:18.855+01:00Hi, I really like the theme. I want to add a banne...Hi, I really like the theme. I want to add a banner to the top right-hand space for an advertiser… how would I do that?Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-3483689298596906177.post-11063567536289654712011-01-23T06:30:13.031+01:002011-01-23T06:30:13.031+01:00I have to state, you chose your words well. The id...I have to state, you chose your words well. The ideas you wrote on your encounters are well placed. This is an incredible blog!Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-3483689298596906177.post-72237135399148965592011-01-18T04:54:29.422+01:002011-01-18T04:54:29.422+01:00I THINK i was one of the test subjects, and boy di...I THINK i was one of the test subjects, and boy did i like the probing!!!Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-3483689298596906177.post-26714154660902101472010-12-30T11:12:25.283+01:002010-12-30T11:12:25.283+01:00Il semble que vous soyez un expert dans ce domaine...Il semble que vous soyez un expert dans ce domaine, vos remarques sont tres interessantes, merci.<br /><br />- DanielAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-3483689298596906177.post-4380399376166088552007-09-14T09:39:00.000+02:002007-09-14T09:39:00.000+02:00I forgot to write about the most important part :)...I forgot to write about the most important part :).<BR/><BR/>Once your views are skinny, you can spec what you want: there should be a form tag, there should be a given user name, etc<BR/><BR/>Views are not easily unit tested, at least not as much as models or helpers are.<BR/><BR/>The real way to test views is in acceptance tests.Papipohttps://www.blogger.com/profile/10673361479709852302noreply@blogger.comtag:blogger.com,1999:blog-3483689298596906177.post-89398404868239407702007-09-14T09:30:00.000+02:002007-09-14T09:30:00.000+02:00You should spec the assignment of the model instan...You should spec the assignment of the model instance to a variable in the controller side.<BR/><BR/>The views should make intensive use of custom helpers. That way you can spec the helpers in isolation, and keep views to a minimum of ruby code.<BR/><BR/>You should avoid using more than one instance variable from the controller in the views.<BR/><BR/>It's preferable that you create <A HREF="http://therailsway.com/2007/6/1/railsconf-recap-skinny-controllers" REL="nofollow">models that don't use the database</A>, since those are as spec-able in isolation as helpers.Papipohttps://www.blogger.com/profile/10673361479709852302noreply@blogger.comtag:blogger.com,1999:blog-3483689298596906177.post-59219220520604484752007-09-13T20:43:00.000+02:002007-09-13T20:43:00.000+02:00This is a nice approach. How is it working out for...This is a nice approach. How is it working out for you papipo? How do you go about testing the corresponding views (if you test them in isolation)?<BR/><BR/>Saludos desde SevillaAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-3483689298596906177.post-14404836705265110312007-09-03T02:30:00.000+02:002007-09-03T02:30:00.000+02:00You got it ;)I understand that being in the habit ...You got it ;)<BR/><BR/>I understand that being in the habit of using expectations makes my approach too "light". It seems that I'm specifying not very much, and giving then too much freedom to the implementation, but in reality that was my intention.<BR/><BR/>If you still don't check the assignation of the model instance to a variable, you are still able to expect the interaction due to what you said in your last comment.<BR/><BR/>The problem here is that explicitness forces you to spec implementation instead of behaviour (at least, partially). In my example, you can use whatever variable name you like. I think that which variable name will be used is still something that should be checked on integration/acceptance, since it's about the interaction with the view. Being more explicit assures you that the things are going fine, but forces the implementation in some ways.<BR/><BR/>Anyway, I'm starting to test this approach, and I know that it assumes, maybe, too many things.<BR/><BR/>About the analysis part, I can't agree with you more :). I was like 3 days thinking about a way to test in real isolation, and this was the result.<BR/><BR/>Thanks for your input.Papipohttps://www.blogger.com/profile/10673361479709852302noreply@blogger.comtag:blogger.com,1999:blog-3483689298596906177.post-11974423927101302422007-09-03T02:09:00.000+02:002007-09-03T02:09:00.000+02:00Oh - I see what you're saying now about the call t...Oh - I see what you're saying now about the call to new being the only way for the two examples to pass/fail differently. Personally, I think that's too much work to have to do that analysis. I'd rather make it more explicit. I think that what I proposed in my last comment would be a good compromise. You?Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-3483689298596906177.post-81964343867803504622007-09-03T02:07:00.000+02:002007-09-03T02:07:00.000+02:00Well, actually, neither would fail if the action n...Well, actually, neither would fail if the action never called new (not just the second one). I appreciate what you're describing - that the combination of the individual examples tells the whole story - but that part of the story is never specified here.<BR/><BR/>If it were me, I'd add either a specific expectation in the first example that new is called or possibly a post-action state-based expectation in both descriptions that @thing gets assigned to the view. The only way those can pass is if the implementation actually interacts with the model.<BR/><BR/>WDYT?Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-3483689298596906177.post-12054761533384520762007-09-03T01:02:00.000+02:002007-09-03T01:02:00.000+02:00That's right, but it's the "interaction" between t...That's right, but it's the "interaction" between the two examples (the valid model and the invalid one), that makes you sure that the controller WILL call both new and save/save!, since it's the only way that both specs will pass (it's the only way for the controller to know if it must render or redirect). And this is the main point of my post, I guess.<BR/><BR/>Apart from that, I like the alternative expectation, it expresses my intention better than stubbing both save and save! (Although stubbing is enough here).<BR/><BR/>As you say, I could add an expectation on new(), but as I have just said, the "interaction" between opposite examples assures that new() will be called anyway. It's an implied expectation.Papipohttps://www.blogger.com/profile/10673361479709852302noreply@blogger.comtag:blogger.com,1999:blog-3483689298596906177.post-68305291117458904592007-09-02T22:18:00.000+02:002007-09-02T22:18:00.000+02:00Actually, reviewing your original post, there is s...Actually, reviewing your original post, there is something missing. In the second example, if the action never creates a new Thing, there is no failure. You have can simply render 'things/create' and never interact with the model and the spec will pass. So I think that we need one of two things:<BR/><BR/>Either the mock framework should support an 'or' expectation like:<BR/><BR/><B>mock.should_receive(:save).<BR/> and_return(false).<BR/> or_receive(:save!).<BR/> and_raise(ActiveRecord::RecordNotSaved)</B><BR/><BR/>or at the very least the specs should use Thing.should_receive(:new) rather than Thing.stub!(:new).<BR/><BR/>WDYT?Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-3483689298596906177.post-41913230657929766612007-09-02T17:31:00.000+02:002007-09-02T17:31:00.000+02:00Not sure about stubbing Class' new(), maybe it's t...Not sure about stubbing Class' new(), maybe it's too intrusive. We could test it, anyway :).<BR/><BR/>As you pointed out, I can update the helpers:<BR/><BR/><B><BR/>def mock_valid_model(klass)<BR/> mock_model(klass, :save => true, :save! => true, :valid? => true)<BR/>end<BR/><BR/>def mock_invalid_model(klass)<BR/> m = mock_model(klass, :save => false, :valid? => false)<BR/> m.stub!(:save!).and_raise(ActiveRecord::RecordNotSaved)<BR/> m<BR/>end<BR/></B><BR/><BR/>But you don't need to stub create nor create!, since those methods call new() internally.<BR/><BR/>I have just test it, and specs pass:<BR/><B><BR/> def create<BR/> @thing = Thing.create<BR/> if @thing.valid?<BR/> redirect_to thing_url(@thing)<BR/> end<BR/> end<BR/></B><BR/><BR/>and this way too:<BR/><B><BR/> def create<BR/> @thing = Thing.new<BR/> if @thing.save<BR/> redirect_to thing_url(@thing)<BR/> end<BR/> end<BR/><BR/></B><BR/><BR/>Thanks for your input.Papipohttps://www.blogger.com/profile/10673361479709852302noreply@blogger.comtag:blogger.com,1999:blog-3483689298596906177.post-18861348412462087412007-09-02T16:47:00.000+02:002007-09-02T16:47:00.000+02:00ps - I left out the fact that some people prefer t...ps - I left out the fact that some people prefer the create/create! approach. Stubbing those methods as well would give you a lot more flexibility.Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-3483689298596906177.post-34172982929571390942007-09-02T16:44:00.000+02:002007-09-02T16:44:00.000+02:00Very reasonable approach that balances goals well....Very reasonable approach that balances goals well. You probably want to also stub :create, :create! and valid? in both the valid and invalid versions - that would allow you to freely change among any of the Rails methods for making new objects.<BR/><BR/>I wonder if stubbing new on the class object would be good too. Then you can just create mock model (valid or invalid) and your off to the races. I'm just sure if that crosses the line of too much being implicit. WDYT?Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-3483689298596906177.post-87961843746048126182007-08-30T22:59:00.000+02:002007-08-30T22:59:00.000+02:00I agree with the custom methods in models. If you ...I agree with the custom methods in models. If you read the posts about skinny controllers, that is the advice they give.<BR/><BR/>In order to relax expectations and stubs in controller specs, you keep your controller lines to a minimum, usually moving a lot of logic to a custom method in the model.Papipohttps://www.blogger.com/profile/10673361479709852302noreply@blogger.comtag:blogger.com,1999:blog-3483689298596906177.post-76992511473310450092007-08-30T22:34:00.000+02:002007-08-30T22:34:00.000+02:00'Ver nice Papipo. I've been doing a lot of expecta...'Ver nice Papipo. I've been doing a lot of expectation setup in my controller specs and have noticed more than a few times that it bites back. Particularly when changing things like changing includes on finds, etc.. <BR/><BR/>When I do start to get nibbled by things like that I try to look at it as an opportunity to encapsulate the finder into a wrapper method instead, sometimes that seems reasonable.Mike Vincenthttps://www.blogger.com/profile/07720216619463630991noreply@blogger.com