Rick Moynihan
2008-May-28 15:12 UTC
[mocha-developer] Mocking objects to test Rails Controllers
Hi all, I''m currently considering the use of Mocha to aid in writing my Rails unit/functional tests. I currently have a Rails model which mixes in a series of methods to allow it to talk to an external service. The code is roughly of this form: class Person < ActiveRecord::Base include SMSNotifier def send_notification(message) send_sms(number,message) # more code/interactions... end end Assuming I want to test that a call to send_notification calls send_sms on the SMSNotifier module, what is the best way to use Mocha to do this? Obviously I don''t want my tests calls to send_notification to actually do any SMS sending :-) I''m assuming Mocha can monkey-patch it''s own method/expectations over the SMSNotifier module. In Java, I''d use dependency injection, but I''m trying to find the Ruby way here. Also I''ve seen that Rails has a folder called test/mocks, can anyone provide any examples or links as to the use of this in Rails/Mocha? Thanks in advance for your assistance, R.
Rob Sanheim
2008-May-28 15:29 UTC
[mocha-developer] Mocking objects to test Rails Controllers
On Wed, May 28, 2008 at 11:12 AM, Rick Moynihan <rick at calicojack.co.uk> wrote:> Hi all, > > I''m currently considering the use of Mocha to aid in writing my Rails > unit/functional tests. > > I currently have a Rails model which mixes in a series of methods to allow > it to talk to an external service. The code is roughly of this form: > > class Person < ActiveRecord::Base > > include SMSNotifier > > def send_notification(message) > send_sms(number,message) > # more code/interactions... > end > end > > Assuming I want to test that a call to send_notification calls send_sms on > the SMSNotifier module, what is the best way to use Mocha to do this? > Obviously I don''t want my tests calls to send_notification to actually do > any SMS sending :-) > > I''m assuming Mocha can monkey-patch it''s own method/expectations over the > SMSNotifier module. In Java, I''d use dependency injection, but I''m trying > to find the Ruby way here. > > Also I''ve seen that Rails has a folder called test/mocks, can anyone provide > any examples or links as to the use of this in Rails/Mocha? > > Thanks in advance for your assistance,With mocha, this is very simple. Say goodbye to DI, and forget the builtin rails/mocks as well. def test_sends_sms_with_number person = Person.new(:number => "5551234567") person.expects(:send_sms).with("5551234567", "test msg") person.send_notification("test msg") end That test will ensure your sms method gets called, and it also removes its implementation so no actual web service calls are made. - Rob http://robsanheim.com http://thinkrelevance.com
Andrew Vit
2008-May-28 18:16 UTC
[mocha-developer] Mocking objects to test Rails Controllers
I think Rick was asking how to test from a controller. Assuming that the controller intantiates the Person object so you can''t setup with Person.new inside your test, you can do: Person.any_instance.expects(:send_sms) --Andrew Vit On May 28, 2008, at 8:29 AM, Rob Sanheim wrote:> On Wed, May 28, 2008 at 11:12 AM, Rick Moynihan > <rick at calicojack.co.uk> wrote: >> Hi all, >> >> I''m currently considering the use of Mocha to aid in writing my Rails >> unit/functional tests. >> >> I currently have a Rails model which mixes in a series of methods >> to allow >> it to talk to an external service. The code is roughly of this form: >> >> class Person < ActiveRecord::Base >> >> include SMSNotifier >> >> def send_notification(message) >> send_sms(number,message) >> # more code/interactions... >> end >> end >> >> Assuming I want to test that a call to send_notification calls >> send_sms on >> the SMSNotifier module, what is the best way to use Mocha to do this? >> Obviously I don''t want my tests calls to send_notification to >> actually do >> any SMS sending :-) >> >> I''m assuming Mocha can monkey-patch it''s own method/expectations >> over the >> SMSNotifier module. In Java, I''d use dependency injection, but I''m >> trying >> to find the Ruby way here. >> >> Also I''ve seen that Rails has a folder called test/mocks, can >> anyone provide >> any examples or links as to the use of this in Rails/Mocha? >> >> Thanks in advance for your assistance, > > With mocha, this is very simple. Say goodbye to DI, and forget the > builtin rails/mocks as well. > > def test_sends_sms_with_number > person = Person.new(:number => "5551234567") > person.expects(:send_sms).with("5551234567", "test msg") > person.send_notification("test msg") > end > > That test will ensure your sms method gets called, and it also removes > its implementation so no actual web service calls are made. > > - Rob > > http://robsanheim.com > http://thinkrelevance.com > _______________________________________________ > mocha-developer mailing list > mocha-developer at rubyforge.org > http://rubyforge.org/mailman/listinfo/mocha-developer
Rick Moynihan
2008-May-29 16:41 UTC
[mocha-developer] Mocking objects to test Rails Controllers
Andrew Vit wrote:> I think Rick was asking how to test from a controller. Assuming that > the controller intantiates the Person object so you can''t setup with > Person.new inside your test, you can do: > > Person.any_instance.expects(:send_sms)Thanks for this Andrew. You were right about what I was asking, but Rob''s answer gave me enough courage to dive in, and find it pretty much just worked as expected. I had my code mocked and tested (to some degree) within 5 minutes. Yay Mocha! :-) R.