hey, thanks for reading: I have a problem which can be reduced to this, from within an example of mine I call the helper ''expect_call'' which is defined thus: def expect_call(*hash*)* *obj.should_receive(:some_ method).with(*hash*)* *end and in one of my examples the ''expected'' hash is strictly defined as follows expect_call(*{ :some_key => [1,2,3] }*) however my spec fails because it is actually called with *{ :some_key => [1,3,2] } *or maybe *{ :some_key => [2,3,1] } *or *{ :some_key => [2,1,3] } *i.e. the array part is not in the order i ''expect'' BUT i don''t actually care about the order. So I would like to be able to change my one example to something like this: expect_call(*{ *:some_key => [1,2,3]*.ignoring_order }*) does such a concept exist or do I have to change the implementation of expect_call to use some sort of custom matcher - I am reluctant to do this since this method is called in other cases where maybe (for arguments sake) I DO care about array ordering within the hash. Hope someone can solve this for me - MUCH appreciation. James -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110201/0be56c69/attachment-0001.html>
On Feb 1, 2011, at 3:40 AM, James OBrien wrote:> hey, thanks for reading: > > I have a problem which can be reduced to this, > > from within an example of mine I call the helper ''expect_call'' which is defined thus: > > def expect_call(hash) > obj.should_receive(:some_ > method).with(hash) > end > > and in one of my examples the ''expected'' hash is strictly defined as follows > > expect_call({ > :some_key => [1,2,3] > }) > > however my spec fails because it is actually called with > > { > :some_key => [1,3,2] > } > > or maybe > > { > :some_key => [2,3,1] > } > > or > > { > :some_key => [2,1,3] > } > > i.e. the array part is not in the order i ''expect'' BUT i don''t actually care about the order. So I would like to be able to change my one example to something like this: > > expect_call({ > :some_key => [1,2,3].ignoring_order > }) > > does such a concept exist or do I have to change the implementation of expect_call to use some sort of custom matcher - I am reluctant to do this since this method is called in other cases where maybe (for arguments sake) I DO care about array ordering within the hash.rspec-expectations lets you do this: foo.bar.should =~ [1,2,3] This passes as long as the array contains exactly those three elements in any order. You can use this now in conjunction with rspec-mocks, like this: foo.should_receive(:bar) do |hash| hash[:some_key].should =~ [1,2,3] end It''s a bit more verbose than what you''re looking for, but it can get you there with rspec as/is today. Going forward, we might want to consider an array_including argument matcher for rspec-mocks. We already have a hash_including matcher that works like this: foo.should_receive(:bar).with(hash_including(:a => ''b'')) Similarly we could have: foo.should_receive(:bar).with(array_including(1,2,3)) The only problem with this is the name: array_including could mean different things (ordered/unordered, only these elements or subset, etc). The hash_including matcher is specifically about a subset of a hash. But perhaps we could extend this with something like you proposed above: foo.should_receive(:bar).with(array_including(1,2,3)) foo.should_receive(:bar).with(array_including(1,2,3).ingoring_order) foo.should_receive(:bar).with(array_including(1,2,3).only.ingoring_order) The thing is, I''m not sure this is any better than the example I gave above, which is very precise and works today. Thoughts/opinions welcome.> Hope someone can solve this for me - MUCH appreciation.As an aside, when passing a hash as an argument you don''t need to use curly braces, as long as the hash is the last argument to the method. These two are equivalent: expect_call(1, :a, {:some_key => ''some value''}) expect_call(1, :a, :some_key => ''some value'') HTH, David -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110201/9a1b5504/attachment.html>
Awesome, thanks David! there are other entries in the hash so presumably I will need something like this i.e. foo.should_receive(:bar) do |hash| actual = hash[:some_key] hash[:some_key].should =~ [1,2,3] hash.shoul end On Tue, Feb 1, 2011 at 4:43 AM, David Chelimsky <dchelimsky at gmail.com>wrote:> > On Feb 1, 2011, at 3:40 AM, James OBrien wrote: > > hey, thanks for reading: > > I have a problem which can be reduced to this, > > from within an example of mine I call the helper ''expect_call'' which is > defined thus: > > def expect_call(*hash*)* > *obj.should_receive(:some_ > method).with(*hash*)* > *end > > and in one of my examples the ''expected'' hash is strictly defined as > follows > > expect_call(*{ > :some_key => [1,2,3] > }*) > > however my spec fails because it is actually called with > > *{ > :some_key => [1,3,2] > } > > *or maybe > > *{ > :some_key => [2,3,1] > } > > *or > > *{ > :some_key => [2,1,3] > } > > *i.e. the array part is not in the order i ''expect'' BUT i don''t actually > care about the order. So I would like to be able to change my one example to > something like this: > > expect_call(*{ > *:some_key => [1,2,3]*.ignoring_order > }*) > > does such a concept exist or do I have to change the implementation of > expect_call to use some sort of custom matcher - I am reluctant to do this > since this method is called in other cases where maybe (for arguments sake) > I DO care about array ordering within the hash. > > > rspec-expectations lets you do this: > > foo.bar.should =~ [1,2,3] > > This passes as long as the array contains exactly those three elements in > any order. You can use this now in conjunction with rspec-mocks, like this: > > foo.should_receive(:bar) do |hash| > hash[:some_key].should =~ [1,2,3] > end > > It''s a bit more verbose than what you''re looking for, but it can get you > there with rspec as/is today. > > Going forward, we might want to consider an array_including argument > matcher for rspec-mocks. We already have a hash_including matcher that works > like this: > > foo.should_receive(:bar).with(hash_including(:a => ''b'')) > > Similarly we could have: > > foo.should_receive(:bar).with(array_including(1,2,3)) > > The only problem with this is the name: array_including could mean > different things (ordered/unordered, only these elements or subset, etc). > The hash_including matcher is specifically about a subset of a hash. But > perhaps we could extend this with something like you proposed above: > > foo.should_receive(:bar).with(array_including(1,2,3)) > foo.should_receive(:bar).with(array_including(1,2,3).ingoring_order) > foo.should_receive(:bar).with(array_including(1,2,3).only.ingoring_order) > > The thing is, I''m not sure this is any better than the example I gave > above, which is very precise and works today. Thoughts/opinions welcome. > > Hope someone can solve this for me - MUCH appreciation. > > > As an aside, when passing a hash as an argument you don''t need to use curly > braces, as long as the hash is the last argument to the method. These two > are equivalent: > > expect_call(1, :a, {:some_key => ''some value''}) > expect_call(1, :a, :some_key => ''some value'') > > HTH, > David > > > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110201/aa550fd9/attachment.html>
ooops, that sent itself early... . . . there are other entries in the hash so presumably I will need something like this foo.should_receive(:bar) do |hash| actual = hash[:some_key] *hash[:some_key] = nil* hash.should == { :my => ''expected'' :other => 1 :ields => :in_the_hash } actual.should =~ [1,2,3] end i.e. I assert :some_key and ''the rest'' separately. There isn''t a way to do this simpler is there? Thanks again David! On Tue, Feb 1, 2011 at 8:46 AM, James OBrien <james at rapleaf.com> wrote:> Awesome, thanks David! > > there are other entries in the hash so presumably I will need something > like this > > i.e. > > > foo.should_receive(:bar) do |hash| > actual = hash[:some_key] > > hash[:some_key].should =~ [1,2,3] > hash.shoul > end > > > > > On Tue, Feb 1, 2011 at 4:43 AM, David Chelimsky <dchelimsky at gmail.com>wrote: > >> >> On Feb 1, 2011, at 3:40 AM, James OBrien wrote: >> >> hey, thanks for reading: >> >> I have a problem which can be reduced to this, >> >> from within an example of mine I call the helper ''expect_call'' which is >> defined thus: >> >> def expect_call(*hash*)* >> *obj.should_receive(:some_ >> method).with(*hash*)* >> *end >> >> and in one of my examples the ''expected'' hash is strictly defined as >> follows >> >> expect_call(*{ >> :some_key => [1,2,3] >> }*) >> >> however my spec fails because it is actually called with >> >> *{ >> :some_key => [1,3,2] >> } >> >> *or maybe >> >> *{ >> :some_key => [2,3,1] >> } >> >> *or >> >> *{ >> :some_key => [2,1,3] >> } >> >> *i.e. the array part is not in the order i ''expect'' BUT i don''t actually >> care about the order. So I would like to be able to change my one example to >> something like this: >> >> expect_call(*{ >> *:some_key => [1,2,3]*.ignoring_order >> }*) >> >> does such a concept exist or do I have to change the implementation of >> expect_call to use some sort of custom matcher - I am reluctant to do this >> since this method is called in other cases where maybe (for arguments sake) >> I DO care about array ordering within the hash. >> >> >> rspec-expectations lets you do this: >> >> foo.bar.should =~ [1,2,3] >> >> This passes as long as the array contains exactly those three elements in >> any order. You can use this now in conjunction with rspec-mocks, like this: >> >> foo.should_receive(:bar) do |hash| >> hash[:some_key].should =~ [1,2,3] >> end >> >> It''s a bit more verbose than what you''re looking for, but it can get you >> there with rspec as/is today. >> >> Going forward, we might want to consider an array_including argument >> matcher for rspec-mocks. We already have a hash_including matcher that works >> like this: >> >> foo.should_receive(:bar).with(hash_including(:a => ''b'')) >> >> Similarly we could have: >> >> foo.should_receive(:bar).with(array_including(1,2,3)) >> >> The only problem with this is the name: array_including could mean >> different things (ordered/unordered, only these elements or subset, etc). >> The hash_including matcher is specifically about a subset of a hash. But >> perhaps we could extend this with something like you proposed above: >> >> foo.should_receive(:bar).with(array_including(1,2,3)) >> foo.should_receive(:bar).with(array_including(1,2,3).ingoring_order) >> >> foo.should_receive(:bar).with(array_including(1,2,3).only.ingoring_order) >> >> The thing is, I''m not sure this is any better than the example I gave >> above, which is very precise and works today. Thoughts/opinions welcome. >> >> Hope someone can solve this for me - MUCH appreciation. >> >> >> As an aside, when passing a hash as an argument you don''t need to use >> curly braces, as long as the hash is the last argument to the method. These >> two are equivalent: >> >> expect_call(1, :a, {:some_key => ''some value''}) >> expect_call(1, :a, :some_key => ''some value'') >> >> HTH, >> David >> >> >> >> >> _______________________________________________ >> rspec-users mailing list >> rspec-users at rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users >> > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110201/e0756169/attachment-0001.html>
additionally, since my *foo.should_receive(... *expectation * *is actually in a private helper method (''expect_call'') on the example group I will need to pull this code up into a block, since not all callers pass a hash with :some_key set viz: #helper_method *def expect_call foo.should_receiver(:bar) do |hash| yield hash end end* then those examples which dont care about my array ordering problem (or rather care that it is in order!) can just do: *expect_call do |actual_hash| actual_hash.should == {:some => ''expected_value'', :other => [4,5,6]} end* and the one case that does care can do: *expect_call do |actual_hash| actual = **actual_hash[:some_key] **actual_hash**[:some_key] = nil **actual_hash.should == { :my => ''expected'' :other => 1 :ields => :in_the_hash } actual.should =~ [1,2,3] ** end* does this sound sensible? Thanks so much again - I have your book :) and although I''m new to it I really enjoy rspec! On Tue, Feb 1, 2011 at 8:51 AM, James OBrien <james at rapleaf.com> wrote:> ooops, that sent itself early... > > . . . > > there are other entries in the hash so presumably I will need something > like this > > foo.should_receive(:bar) do |hash| > actual = hash[:some_key] > *hash[:some_key] = nil* > hash.should == { > :my => ''expected'' > :other => 1 > :ields => :in_the_hash > } > actual.should =~ [1,2,3] > > end > > i.e. I assert :some_key and ''the rest'' separately. > > There isn''t a way to do this simpler is there? > > Thanks again David! > > > On Tue, Feb 1, 2011 at 8:46 AM, James OBrien <james at rapleaf.com> wrote: > >> Awesome, thanks David! >> >> there are other entries in the hash so presumably I will need something >> like this >> >> i.e. >> >> >> foo.should_receive(:bar) do |hash| >> actual = hash[:some_key] >> >> hash[:some_key].should =~ [1,2,3] >> hash.shoul >> end >> >> >> >> >> On Tue, Feb 1, 2011 at 4:43 AM, David Chelimsky <dchelimsky at gmail.com>wrote: >> >>> >>> On Feb 1, 2011, at 3:40 AM, James OBrien wrote: >>> >>> hey, thanks for reading: >>> >>> I have a problem which can be reduced to this, >>> >>> from within an example of mine I call the helper ''expect_call'' which is >>> defined thus: >>> >>> def expect_call(*hash*)* >>> *obj.should_receive(:some_ >>> method).with(*hash*)* >>> *end >>> >>> and in one of my examples the ''expected'' hash is strictly defined as >>> follows >>> >>> expect_call(*{ >>> :some_key => [1,2,3] >>> }*) >>> >>> however my spec fails because it is actually called with >>> >>> *{ >>> :some_key => [1,3,2] >>> } >>> >>> *or maybe >>> >>> *{ >>> :some_key => [2,3,1] >>> } >>> >>> *or >>> >>> *{ >>> :some_key => [2,1,3] >>> } >>> >>> *i.e. the array part is not in the order i ''expect'' BUT i don''t actually >>> care about the order. So I would like to be able to change my one example to >>> something like this: >>> >>> expect_call(*{ >>> *:some_key => [1,2,3]*.ignoring_order >>> }*) >>> >>> does such a concept exist or do I have to change the implementation of >>> expect_call to use some sort of custom matcher - I am reluctant to do this >>> since this method is called in other cases where maybe (for arguments sake) >>> I DO care about array ordering within the hash. >>> >>> >>> rspec-expectations lets you do this: >>> >>> foo.bar.should =~ [1,2,3] >>> >>> This passes as long as the array contains exactly those three elements in >>> any order. You can use this now in conjunction with rspec-mocks, like this: >>> >>> foo.should_receive(:bar) do |hash| >>> hash[:some_key].should =~ [1,2,3] >>> end >>> >>> It''s a bit more verbose than what you''re looking for, but it can get you >>> there with rspec as/is today. >>> >>> Going forward, we might want to consider an array_including argument >>> matcher for rspec-mocks. We already have a hash_including matcher that works >>> like this: >>> >>> foo.should_receive(:bar).with(hash_including(:a => ''b'')) >>> >>> Similarly we could have: >>> >>> foo.should_receive(:bar).with(array_including(1,2,3)) >>> >>> The only problem with this is the name: array_including could mean >>> different things (ordered/unordered, only these elements or subset, etc). >>> The hash_including matcher is specifically about a subset of a hash. But >>> perhaps we could extend this with something like you proposed above: >>> >>> foo.should_receive(:bar).with(array_including(1,2,3)) >>> foo.should_receive(:bar).with(array_including(1,2,3).ingoring_order) >>> >>> foo.should_receive(:bar).with(array_including(1,2,3).only.ingoring_order) >>> >>> The thing is, I''m not sure this is any better than the example I gave >>> above, which is very precise and works today. Thoughts/opinions welcome. >>> >>> Hope someone can solve this for me - MUCH appreciation. >>> >>> >>> As an aside, when passing a hash as an argument you don''t need to use >>> curly braces, as long as the hash is the last argument to the method. These >>> two are equivalent: >>> >>> expect_call(1, :a, {:some_key => ''some value''}) >>> expect_call(1, :a, :some_key => ''some value'') >>> >>> HTH, >>> David >>> >>> >>> >>> >>> _______________________________________________ >>> rspec-users mailing list >>> rspec-users at rubyforge.org >>> http://rubyforge.org/mailman/listinfo/rspec-users >>> >> >> >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110201/5aa990a5/attachment.html>
Does this strike anyone else as odd? Don''t you think the test should actually be written IN to the code itself? I guess I''m soft of stipulating a new language here, but perhaps Ruby is flexible enough to enable this. Surely as the private methods of a class change, the testing code HAS to change... therefore isn''t it best to actually write the rspec-level tests into the classes themselves as context-sensitive-optionally loaded or not depending on whether you''re in testing mode or not Julian On 02/02/2011, at 4:01 AM, James OBrien wrote:> additionally, > > since my > > foo.should_receive(... > > expectation > > is actually in a private helper method (''expect_call'') on the example group I will need to pull this code up into a block, since not all callers pass a hash with :some_key set > > viz: > > #helper_method > def expect_call > foo.should_receiver(:bar) do |hash| > yield hash > end > end > > then those examples which dont care about my array ordering problem (or rather care that it is in order!) can just do: > > expect_call do |actual_hash| > actual_hash.should == {:some => ''expected_value'', :other => [4,5,6]} > end > > and the one case that does care can do: > > expect_call do |actual_hash| > actual = actual_hash[:some_key] > actual_hash[:some_key] = nil > actual_hash.should == { > :my => ''expected'' > :other => 1 > :ields => :in_the_hash > } > actual.should =~ [1,2,3] > end > > does this sound sensible? > > Thanks so much again - I have your book :) and although I''m new to it I really enjoy rspec! > > On Tue, Feb 1, 2011 at 8:51 AM, James OBrien <james at rapleaf.com> wrote: > ooops, that sent itself early... > > . . . > > there are other entries in the hash so presumably I will need something like this > > foo.should_receive(:bar) do |hash| > actual = hash[:some_key] > hash[:some_key] = nil > hash.should == { > :my => ''expected'' > :other => 1 > :ields => :in_the_hash > } > actual.should =~ [1,2,3] > > end > > i.e. I assert :some_key and ''the rest'' separately. > > There isn''t a way to do this simpler is there? > > Thanks again David! > > > On Tue, Feb 1, 2011 at 8:46 AM, James OBrien <james at rapleaf.com> wrote: > Awesome, thanks David! > > there are other entries in the hash so presumably I will need something like this > > i.e. > > > foo.should_receive(:bar) do |hash| > actual = hash[:some_key] > > hash[:some_key].should =~ [1,2,3] > hash.shoul > end > > > > > On Tue, Feb 1, 2011 at 4:43 AM, David Chelimsky <dchelimsky at gmail.com> wrote: > > On Feb 1, 2011, at 3:40 AM, James OBrien wrote: > >> hey, thanks for reading: >> >> I have a problem which can be reduced to this, >> >> from within an example of mine I call the helper ''expect_call'' which is defined thus: >> >> def expect_call(hash) >> obj.should_receive(:some_ >> method).with(hash) >> end >> >> and in one of my examples the ''expected'' hash is strictly defined as follows >> >> expect_call({ >> :some_key => [1,2,3] >> }) >> >> however my spec fails because it is actually called with >> >> { >> :some_key => [1,3,2] >> } >> >> or maybe >> >> { >> :some_key => [2,3,1] >> } >> >> or >> >> { >> :some_key => [2,1,3] >> } >> >> i.e. the array part is not in the order i ''expect'' BUT i don''t actually care about the order. So I would like to be able to change my one example to something like this: >> >> expect_call({ >> :some_key => [1,2,3].ignoring_order >> }) >> >> does such a concept exist or do I have to change the implementation of expect_call to use some sort of custom matcher - I am reluctant to do this since this method is called in other cases where maybe (for arguments sake) I DO care about array ordering within the hash. > > rspec-expectations lets you do this: > > foo.bar.should =~ [1,2,3] > > This passes as long as the array contains exactly those three elements in any order. You can use this now in conjunction with rspec-mocks, like this: > > foo.should_receive(:bar) do |hash| > hash[:some_key].should =~ [1,2,3] > end > > It''s a bit more verbose than what you''re looking for, but it can get you there with rspec as/is today. > > Going forward, we might want to consider an array_including argument matcher for rspec-mocks. We already have a hash_including matcher that works like this: > > foo.should_receive(:bar).with(hash_including(:a => ''b'')) > > Similarly we could have: > > foo.should_receive(:bar).with(array_including(1,2,3)) > > The only problem with this is the name: array_including could mean different things (ordered/unordered, only these elements or subset, etc). The hash_including matcher is specifically about a subset of a hash. But perhaps we could extend this with something like you proposed above: > > foo.should_receive(:bar).with(array_including(1,2,3)) > foo.should_receive(:bar).with(array_including(1,2,3).ingoring_order) > foo.should_receive(:bar).with(array_including(1,2,3).only.ingoring_order) > > The thing is, I''m not sure this is any better than the example I gave above, which is very precise and works today. Thoughts/opinions welcome. > >> Hope someone can solve this for me - MUCH appreciation. > > > As an aside, when passing a hash as an argument you don''t need to use curly braces, as long as the hash is the last argument to the method. These two are equivalent: > > expect_call(1, :a, {:some_key => ''some value''}) > expect_call(1, :a, :some_key => ''some value'') > > HTH, > David > > > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users > > > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110202/5b3e9da3/attachment.html>
I don''t fully understand this response.. The private method I mentioned was a helper created by me in test code on the example group. Still very interested On Feb 1, 2011 7:28 PM, "Julian Leviston" <julian at leviston.net> wrote: Does this strike anyone else as odd? Don''t you think the test should actually be written IN to the code itself? I guess I''m soft of stipulating a new language here, but perhaps Ruby is flexible enough to enable this. Surely as the private methods of a class change, the testing code HAS to change... therefore isn''t it best to actually write the rspec-level tests into the classes themselves as context-sensitive-optionally loaded or not depending on whether you''re in testing mode or not Julian On 02/02/2011, at 4:01 AM, James OBrien wrote:> additionally, > > since my > > foo.should_recei..._______________________________________________ rspec-users mailing list rspec-users at rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110201/c271fc35/attachment.html>
Sorry it was a knee-jerk reaction that was prompted by what you wrote, but not necessarily even connected to it. Essentially, I''ve been wondering/thinking about this for a very long time (since about 15 years ago when I started writing smalltalk code). I think a general principle of code is that it should be specced from the inside out and simultaneously from the outside in. We have things like cucumber to generally spec from the outside in (ie define an interface according to the "user" what or whoever that may be), and we have things like rspec to spec from the inside out.... ...however inside-out specs should be built inline with the code they spec, surely? I mean, just like you *should* have comments and documentation built in, the spec should almost build a bridge from the documentation to the code... It seems rspec is incredibly close to this, much closer than cucumber is to be a very useable outside-in spec system. Essentially I''d stipulate a flow of development that went something like this: 1. Plan 2. Put Plan and Documentation in source code with placeholders 3. Build Spec 4. Build Code An architecture that, when bootstrapped, tests itself to make sure it''s not borked before the code runs. (ie it does self-check on startup, essentially). Julian. On 02/02/2011, at 2:36 PM, James OBrien wrote:> I don''t fully understand this response.. > > The private method I mentioned was a helper created by me in test code on the example group. > > Still very interested > > >> On Feb 1, 2011 7:28 PM, "Julian Leviston" <julian at leviston.net> wrote: >> >> Does this strike anyone else as odd? >> >> Don''t you think the test should actually be written IN to the code itself? >> >> I guess I''m soft of stipulating a new language here, but perhaps Ruby is flexible enough to enable this. >> >> Surely as the private methods of a class change, the testing code HAS to change... therefore isn''t it best to actually write the rspec-level tests into the classes themselves as context-sensitive-optionally loaded or not depending on whether you''re in testing mode or not >> >> Julian >> >> >> >> On 02/02/2011, at 4:01 AM, James OBrien wrote: >> >> > additionally, >> > >> > since my >> > >> > foo.should_recei... >> >> >> _______________________________________________ >> rspec-users mailing list >> rspec-users at rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users > > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110202/36d56ab1/attachment-0001.html>
Sorry but I disagree. Specs should define only the external behavior of an object or service - allowing for confident implementation adjustments against a trusted suite of tests. What you''re describing would make refactoring very hard. I think what you say goes against a lot of established theory and best practise. I would like to draw this back to the original question Take care James On Feb 1, 2011 8:16 PM, "Julian Leviston" <julian at leviston.net> wrote: Sorry it was a knee-jerk reaction that was prompted by what you wrote, but not necessarily even connected to it. Essentially, I''ve been wondering/thinking about this for a very long time (since about 15 years ago when I started writing smalltalk code). I think a general principle of code is that it should be specced from the inside out and simultaneously from the outside in. We have things like cucumber to generally spec from the outside in (ie define an interface according to the "user" what or whoever that may be), and we have things like rspec to spec from the inside out.... ...however inside-out specs should be built inline with the code they spec, surely? I mean, just like you *should* have comments and documentation built in, the spec should almost build a bridge from the documentation to the code... It seems rspec is incredibly close to this, much closer than cucumber is to be a very useable outside-in spec system. Essentially I''d stipulate a flow of development that went something like this: 1. Plan 2. Put Plan and Documentation in source code with placeholders 3. Build Spec 4. Build Code An architecture that, when bootstrapped, tests itself to make sure it''s not borked before the code runs. (ie it does self-check on startup, essentially). Julian. On 02/02/2011, at 2:36 PM, James OBrien wrote:> I don''t fully understand this response.. > > The..._______________________________________________ rspec-users mailing list rspec-users at rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110201/b50ec4ce/attachment.html>
El 02/02/2011, a las 02:28, Julian Leviston escribi?:> Surely as the private methods of a class change, the testing code HAS to change...That statement sets off all sorts of alarm bells for me. In order for your specs to be non-brittle, they should be concerned with the externally-visible behavior of the code and not with the internal implementation details. For me, private methods fall under "internal implementation details". Being non-brittle and focussed on externally-visible behavior rather than implementation is a valuable attribute for a spec suite to have, because it allows us to refactor and improve the code with confidence that the behavior remains unchanged, but without having to engage in duplicative and error-prone updating of our specs to match the internal changes in implementation. So, if you''re feeling the need to spec private methods, its an indication that you could be doing something better, because you''re either: - specifying internal implementation details (and if that''s the case, why are you specifying it?); or - you''ve made something private that shouldn''t really be that way (and in that case, there are various refactorings you can use to restructure the code in order to make it more amenable to testing) Cheers, Wincent
I agree Vincent Can people however please use this trail to help me with my original query. I repeat the private method is declared on the test example group. This is not inside implemenraton code. On Feb 1, 2011 9:21 PM, "Wincent Colaiuta" <win at wincent.com> wrote: El 02/02/2011, a las 02:28, Julian Leviston escribi?:> Surely as the private methods of a class change, the testing code HAS tochange... That statement sets off all sorts of alarm bells for me. In order for your specs to be non-brittle, they should be concerned with the externally-visible behavior of the code and not with the internal implementation details. For me, private methods fall under "internal implementation details". Being non-brittle and focussed on externally-visible behavior rather than implementation is a valuable attribute for a spec suite to have, because it allows us to refactor and improve the code with confidence that the behavior remains unchanged, but without having to engage in duplicative and error-prone updating of our specs to match the internal changes in implementation. So, if you''re feeling the need to spec private methods, its an indication that you could be doing something better, because you''re either: - specifying internal implementation details (and if that''s the case, why are you specifying it?); or - you''ve made something private that shouldn''t really be that way (and in that case, there are various refactorings you can use to restructure the code in order to make it more amenable to testing) Cheers, Wincent _______________________________________________ rspec-users mailing list rspec-users at rubyforge.org ... -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://rubyforge.org/pipermail/rspec-users/attachments/20110201/e0c2f995/attachment.html>
On 02/02/2011, at 3:47 PM, Wincent Colaiuta wrote:> El 02/02/2011, a las 02:28, Julian Leviston escribi?: > >> Surely as the private methods of a class change, the testing code HAS to change... > > That statement sets off all sorts of alarm bells for me. > > In order for your specs to be non-brittle, they should be concerned with the externally-visible behavior of the code and not with the internal implementation details. For me, private methods fall under "internal implementation details". > > Being non-brittle and focussed on externally-visible behavior rather than implementation is a valuable attribute for a spec suite to have, because it allows us to refactor and improve the code with confidence that the behavior remains unchanged, but without having to engage in duplicative and error-prone updating of our specs to match the internal changes in implementation. > > So, if you''re feeling the need to spec private methods, its an indication that you could be doing something better, because you''re either: > > - specifying internal implementation details (and if that''s the case, why are you specifying it?); or > > - you''ve made something private that shouldn''t really be that way (and in that case, there are various refactorings you can use to restructure the code in order to make it more amenable to testing) > > Cheers, > Wincent >That''s hopefully already fairly obvious. Yes, I agree. Program to an interface. The idea is pretty much scope: ie, it depends what you''re testing... it''s the behaviour of the thing you''re testing that is important... We have application-level scope ("behaviour testing"), class-level scope (testing that the class does what it''s supposed to) and method-level scope dependant on what we''re programming, right? If I''m programming a method, I want to test that it does certain things (preferably the things it''s supposed to do, right? This is, after all, what a spec is....). Binding a set of components together to build an enclosing component, each component should have tests... including any enclosing components. Encapsulation of tests... :-) Julian.