Hi guys, got this problem with creating such a thing... hope anyone could help.. the problem: ok, now i have this mock object that would simulate a external rpc call. eg require ''models/xmlrpc_agent'' class XmlrpcAgent def create(params) 200 end end but the value of the value returned is fixed. which is quite hard for me to test the controller when different values are returned from the rpc call.... is there a way to make the number returned dynamic?? Dynamic in the sense that i can pre-define the returned number in the functional test case to simulate the different kind of situation that might arise.... -burninglegion -- Posted via http://www.ruby-forum.com/.
On Apr 19, 2006, at 9:19 PM, bao lee wrote:> Hi guys, got this problem with creating such a thing... hope anyone > could help.. > > the problem: > > ok, now i have this mock object that would simulate a external rpc > call. > eg > > require ''models/xmlrpc_agent'' > > class XmlrpcAgent > > def create(params) > 200 > end > endThis is a stub, not a mock.> but the value of the value returned is fixed. which is quite hard > for me > to test the controller when different values are returned from the rpc > call.... is there a way to make the number returned dynamic?? > Dynamic in > the sense that i can pre-define the returned number in the functional > test case to simulate the different kind of situation that might > arise....I use the following pattern when I use stubs, taking advantage of Ruby''s open classes. My flickr interface use open-uri to do its work, so I inject my own open that will be called before Kernel''s. I record the passed URIs and give the positional response. This makes it easy to verify the method DTRT. class Flickr attr_accessor :responses, :uris def open(uri) @uris << uri yield StringIO.new(@responses.shift) end end class FlickrTest < Test::Unit::TestCase #... def test_find_email @flickr.responses << <<-EOF <?xml version="1.0" encoding="utf-8" ?> <rsp stat="ok"> <user id="50178138@N00" nsid="50178138@N00"> <username>drbrain</username> </user> </rsp> EOF nsid = @flickr.find_email :find_email => ''drbrain@segment7.net'' assert_equal 1, @flickr.uris.length assert_equal ''http://flickr.com/services/rest/? api_key=API_KEY&find_email=dr brain%40segment7.net&method=flickr.people.findByEmail'', @flickr.uris.first assert_equal ''50178138@N00'', nsid end end -- Eric Hodel - drbrain@segment7.net - http://blog.segment7.net This implementation is HODEL-HASH-9600 compliant http://trackmap.robotcoop.com
Hi eric, sory for the confusion which i first came upon... the ruby on rails book didnt tell me much about stubs and also the differences between the 2.... ok so after reading thorugh the code i got a rough idea about it but it seems to be a bit complicated....btw does this apply to functional test also?? -- Posted via http://www.ruby-forum.com/.
Use FlexMock, quite simple and powerful. -- Company - http://primalgrasp.com Thoughts - http://deezsombor.blogspot.com
> > Use FlexMock, quite simple and powerful. >Thanks for the pointer -------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060420/0b97f197/attachment.html
I wrote an article about selectively overriding methods in particular instances of objects for testing - I called them "Partial Mock Objects". http://karmiccoding.com/articles/2006/03/11/under-the-hood-with-ruby-partial-mock-objects-for-unit-testing Cheers, -David Felstead On 4/20/06, Thibaut Barr?re <thibaut.barrere@gmail.com> wrote:> > > Use FlexMock, quite simple and powerful. > > > > Thanks for the pointer > > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails > > >
David Felstead wrote:> I wrote an article about selectively overriding methods in particular > instances of objects for testing - I called them "Partial Mock > Objects". > > http://karmiccoding.com/articles/2006/03/11/under-the-hood-with-ruby-partial-mock-objects-for-unit-testing > > Cheers, > > -David Felsteadyeah i have seen that post... great post... -- Posted via http://www.ruby-forum.com/.
bao lee wrote:> David Felstead wrote: >> I wrote an article about selectively overriding methods in particular >> instances of objects for testing - I called them "Partial Mock >> Objects". >> >> http://karmiccoding.com/articles/2006/03/11/under-the-hood-with-ruby-partial-mock-objects-for-unit-testing >> >> Cheers, >> >> -David Felstead > > yeah i have seen that post... great post...btw i think that that post only works with instances of objects... issit possible the change the class itself rather than instance of the class? cos my problem is the stub that i used is to replace something in the controller algorithm and i cant change it within the controller... so it does not work when i try override_method(XmlrpcAgent,:create) { 502 } where XmlrpcAgent is the class name and :create is the name of the function.... is there any tweaks to the code you have done that could allow that to happen?? thanks for you help -- Posted via http://www.ruby-forum.com/.
bao lee wrote: hey David Felstead , i think i have found what i wanted... from your code : def override_method(obj,method_name,&block) #klass = class <<obj; self; end #klass.send( :undef_method , method_name ) #klass.send( :define_method, method_name, block) obj.send(:undef_method,method_name) obj.send(:define_method,method_name,block) end the one commented is the your original code, the one uncommented is the one i wrote.... this way the class method is changed completely and my testing went as smooth as it can get!!! thanks for the enlightenment provided!! -- Posted via http://www.ruby-forum.com/.
bao lee wrote:> def override_method(obj,method_name,&block) > #klass = class <<obj; self; end > #klass.send( :undef_method , method_name ) > #klass.send( :define_method, method_name, block) > obj.send(:undef_method,method_name) > obj.send(:define_method,method_name,block) > endok... i found a disadvantage when doing this way....that is when writing my tests, when i called this override method.. the next test that used the overrided class method will not be revert back automatically....eg. for the class in test/mock/test : class XmlrpcAgent def create(params) 200 end end in test_controller : if i called override_method(XmlrpcAgent,:create){ 502 } in one of my test case then the next test case that used XmlrpcAgent class will now return 502 rather than 200.... so the next test case that need to use XmlrpcAgent will have to override the method to its own use.... well a bit of hard coding here... but i think that would be the best solution i could think of currently... -- Posted via http://www.ruby-forum.com/.
Hey there, Yeah, the aim of the code provided is to only override the method specified in a particular instance of the object. If you want to do it for the entire class, what you have there will work, but as you''ve seen it will carry through for the subsequent tests. If you want to revert it back, you would have to put something in your test''s ''teardown'' method to bring it back... Have a look at the ''alias_method'' call in the Ruby API - instead of using ''undefine_method'' you could alias the method being overriden to another same ("#{method_name}_old", for example) and in the teardown you could alias it back. I _think_ that would work. Cheers! -David Felstead On 4/21/06, bao lee <leewen_colour@hotmail.com> wrote:> bao lee wrote: > > > def override_method(obj,method_name,&block) > > #klass = class <<obj; self; end > > #klass.send( :undef_method , method_name ) > > #klass.send( :define_method, method_name, block) > > obj.send(:undef_method,method_name) > > obj.send(:define_method,method_name,block) > > end > > ok... i found a disadvantage when doing this way....that is when writing > my tests, when i called this override method.. the next test that used > the overrided class method will not be revert back automatically....eg. > for the class in test/mock/test : > class XmlrpcAgent > > def create(params) > 200 > end > end > > in test_controller : > if i called override_method(XmlrpcAgent,:create){ 502 } in one of my > test case > > then the next test case that used XmlrpcAgent class will now return 502 > rather than 200.... > so the next test case that need to use XmlrpcAgent will have to override > the method to its own use.... well a bit of hard coding here... but i > think that would be the best solution i could think of currently... > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
David Felstead wrote:> Hey there, > > Yeah, the aim of the code provided is to only override the method > specified in a particular instance of the object. If you want to do > it for the entire class, what you have there will work, but as you''ve > seen it will carry through for the subsequent tests. If you want to > revert it back, you would have to put something in your test''s > ''teardown'' method to bring it back... > > Have a look at the ''alias_method'' call in the Ruby API - instead of > using ''undefine_method'' you could alias the method being overriden to > another same ("#{method_name}_old", for example) and in the teardown > you could alias it back. I _think_ that would work. > > Cheers! > > -David Felsteadhmmm... interesting... ok i will go and take a look about that and post any updates i have... thanks !! -- Posted via http://www.ruby-forum.com/.