Hello! I''ve been lurking in the list a while, and now I would like to ask you a somewhat "noobish" question... This is the first time I''ve run across this particular problem, so I''m not sure what to do. I''m sure this is so common that''s in a textbook somewhere, but what is the best way to write specs for code that calls out to an external server? I''ve just started working on a project that will use AMQP messaging (and the "amqp" gem), and most of the code I''ve written so far is all about talking to a messaging server. The only alternatives I saw for writing specs were starting said server, and mocking/stubbing out all the code that would talk to it. I went witht he second one, but I feel it''s a fragile approach that won''t actually allow me to find bugs, since everything is mocked out. What is the best way to do this? -- Bira http://compexplicita.wordpress.com http://compexplicita.tumblr.com
On Wed, Mar 4, 2009 at 4:54 AM, Bira <u.alberton at gmail.com> wrote:> Hello! > > I''ve been lurking in the list a while, and now I would like to ask you > a somewhat "noobish" question... This is the first time I''ve run > across this particular problem, so I''m not sure what to do. I''m sure > this is so common that''s in a textbook somewhere, but what is the best > way to write specs for code that calls out to an external server? > > I''ve just started working on a project that will use AMQP messaging > (and the "amqp" gem), and most of the code I''ve written so far is all > about talking to a messaging server. The only alternatives I saw for > writing specs were starting said server, and mocking/stubbing out all > the code that would talk to it. I went witht he second one, but I feel > it''s a fragile approach that won''t actually allow me to find bugs, > since everything is mocked out. What is the best way to do this?I''m not familiar w/ amqp in particular, but one "good" approach is to use mock objects to evolve a protocol for this service in the language of your app, and then write an adapter for amqp with a few system level tests in place to verify happy paths. This approach does a few good things. * Keeps you focused on the business domain while writing the business objects, because you''re not sidetracked by the details of messaging. * Keeps the suite of specs running fast * Makes it easy to choose a different messaging API later, because all of the code that depends directly on that API lives in the adapter. HTH, David> > -- > Bira > http://compexplicita.wordpress.com > http://compexplicita.tumblr.com > _______________________________________________ > rspec-users mailing list > rspec-users at rubyforge.org > http://rubyforge.org/mailman/listinfo/rspec-users >
David Chelimsky wrote:> On Wed, Mar 4, 2009 at 4:54 AM, Bira <u.alberton at gmail.com> wrote: > >> Hello! >> >> I''ve been lurking in the list a while, and now I would like to ask you >> a somewhat "noobish" question... This is the first time I''ve run >> across this particular problem, so I''m not sure what to do. I''m sure >> this is so common that''s in a textbook somewhere, but what is the best >> way to write specs for code that calls out to an external server? >> >> I''ve just started working on a project that will use AMQP messaging >> (and the "amqp" gem), and most of the code I''ve written so far is all >> about talking to a messaging server. The only alternatives I saw for >> writing specs were starting said server, and mocking/stubbing out all >> the code that would talk to it. I went witht he second one, but I feel >> it''s a fragile approach that won''t actually allow me to find bugs, >> since everything is mocked out. What is the best way to do this? >> > > I''m not familiar w/ amqp in particular, but one "good" approach is to > use mock objects to evolve a protocol for this service in the language > of your app, and then write an adapter for amqp with a few system > level tests in place to verify happy paths. > > This approach does a few good things. > > * Keeps you focused on the business domain while writing the business > objects, because you''re not sidetracked by the details of messaging. > * Keeps the suite of specs running fast > * Makes it easy to choose a different messaging API later, because all > of the code that depends directly on that API lives in the adapter. > > HTH, > David > > >Bria, In the past, I have done exactly as David has suggested. I have my cucumber features use the actual messaging system to verify that everything is hooked up and is working correctly. I then use a combination of null and fake adapters in my specs to keep them fast and focused on testing the object''s responsibility. Doing this required that an adapter layer be introduced. The nice thing about this, as David also points out, is that you can then easily swap out another messaging system by simply writing a new adapter. I have actually open soured my efforts (and my coworker''s, Chris Wyckoff) so you can use, or at least get ideas from, the library here: https://github.com/bmabey/rosetta_queue/tree You can use currently use the library with messaging systems that speak AMQP or stomp. Additionally, I have blogged about how we used Cucumber and this library to integrate our distributed systems: http://www.benmabey.com/2009/02/17/using-cucumber-to-integrate-distributed-systems-and-test-messaging/ HTH, Ben
David and Ben, Thank you very much for your advice :). -- Bira http://compexplicita.wordpress.com http://compexplicita.tumblr.com
Bira, and Ben, Bira wrote:> David and Ben, > > Thank you very much for your advice :).Hi, Alexis here from RabbitMQ. +1 to what Ben said. Ben - that''s a really nice project you''ve set up there Ben. Could you introduce it on the rabbitmq-discuss list some time perhaps? Bira - may I leave you with some links that may also help: * Ruby client discusion group: http://groups.google.com/group/ruby-amqp/ * Intro info, Ruby links and ''how to create your own client'': http://www.rabbitmq.com/how.html Hope this helps! alexis> -- > Bira > http://compexplicita.wordpress.com > http://compexplicita.tumblr.com-- Posted via http://www.ruby-forum.com/.