= RR RR (Double Ruby) is a double framework that features a rich selection of double techniques and a terse syntax. http://xunitpatterns.com/Test%20Double.html Currently RR implements mocks, stubs, and probes. It is a goal of RR to support a wide range of double techniques and patterns. == Mocks http://xunitpatterns.com/Mock%20Object.html view = controller.template mock(view).render(:partial => "user_info") {"Information"} # or mock(view) do render(:partial => "user_info") {"Information"} end == Stubs http://xunitpatterns.com/Test%20Stub.html jane = User.new stub(User).find('42') {jane} == Mock Probes Add verifications that a method was called while actually calling it. The following example verifies render partial will be called and renders the partial. view = controller.template mock.probe(view).render(:partial => "right_navigation") mock.probe(view).render(:partial => "user_info") do |html| html.should include("John Doe") "Different html" end Probes support after_call callbacks. This is useful for Stubbing out a class method and getting its return value. You can also change the return value. This technique is also useful for verifying that you are mocking exists and functions proberly, thereby testing you interface. For example, using ActiveRecord: probe(User).find('5') do |user| mock.probe(user).projects do |projects| projects[0..3] end mock(user).valid? {false} user end == Stub Probes Intercept the return value of a method call. The following example verifies render partial will be called and renders the partial. view = controller.template stub.probe(view).render(:partial => "user_info") do |html| html.should include("Joe Smith") html end == Block Syntax script = MyScript.new mock(script) do |m| m.system("cd #{RAILS_ENV}") {true} m.system("rake foo:bar") {true} m.system("rake baz") {true} end == Terse Syntax One of the goals of RR is to make doubles more scannable. This is accomplished by removing words from a double declaration. Here is RR compared to other mock frameworks: flexmock(User).should_receive(:find).with('42').and_return(jane) # Flexmock User.should_receive(:find).with('42').and_return(jane) # Rspec User.expects(:find).with('42').returns {jane} # Mocha User.should_receive(:find).with('42') {jane} # Rspec using return value blocks mock(User).find('42') {jane} # RR == Special Thanks To With any development effort, there are countless people who have contributed to making it possible. We all are standing on the shoulders of giants. * Pivotal Labs for sponsoring RR development * Parker Thompson for pairing with me * Felix Morio for pairing with me * David Chelimsky for encouragement to make the RR framework, for developing the Rspec mock framework, and syntax ideas * Gerald Meszaros for his excellent book "xUnit Test Patterns" * Dan North for syntax ideas * Jim Weirich for developing Flexmock, the first Terse ruby mock framework * James Mead for developing Mocha * Aslak Hellesoy for Developing Rspec * Stephen Baker for Developing Rspec * Dave Astels for some BDD inspiration