rr

a test double framework for Ruby with a succinct syntax
Current version: 3.1.1

RR is a Ruby library that lets you create and work with test doubles. Test doubles are useful because they let you temporarily replace parts of your code during a test, similar to how a producer might use a stunt double to temporarily take the place of an actor in a movie. You can use a test double to override a method on an object with a simpler implementation; create an object that responds to a particular method; or even establish an expectation that a particular method should be called on a object, which will be verified after your test runs.

RR features a succinct syntax which aims to makes it easier to translate main code to test double form by matching double definitions on methods as closely as possible to actual invocations of those methods. In addition, RR differs from existing mock / test double frameworks by staying out of the global Object class; instead, it limits its scope to your surrounding test case, and asks that beyond this scope you explicitly wrap any objects on which you want to define test doubles.

Finally, RR provides adapters so you can integrate it with your test framework of choice, whether RSpec, Test::Unit or MiniTest/MiniSpec. RR is tested against all active Ruby versions.

RR was created by Brian Takita. Previously maintained by Elliot Winkler and currently by Kouhei Sutou.

Examples

RR includes a rich set of test double strategies. Following is a sample of what RR looks like.


Stubs

    # Stub a method to return nothing
    stub(object).foo
    stub(MyClass).foo { 'bar' }

    # Stub a method to always return a value
    stub(object).foo { 'bar' }
    stub(MyClass).foo { 'bar' }

    # Stub a method to return a value when called with certain arguments
    stub(object).foo(1, 2) { 'bar' }
    stub(MyClass).foo(1, 2) { 'bar' }
  

Mocks

    # Create an expectation on a method
    mock(object).foo
    mock(MyClass).foo

    # Create an expectation on a method
    # and stub it to always return a value
    mock(object).foo { 'bar' }
    mock(MyClass).foo { 'bar' }

    # Create an expectation on a method with certain arguments
    # and stub it to return a value when called that way
    mock(object).foo(1, 2) { 'bar' }
    mock(MyClass).foo(1, 2) { 'bar' }
  

Proxies

    # Intercept a existing method without completely overriding it,
    # and create a new return value from the existing one
    stub.proxy(object).foo {|str| str.upcase }
    stub.proxy(MyClass).foo {|str| str.upcase }

    # Do the same thing except also create an expectation
    mock.proxy(object).foo {|str| str.upcase }
    mock.proxy(MyClass).foo {|str| str.upcase }

    # Intercept a class's new method and define a double on the return value
    stub.proxy(MyClass).new {|obj| stub(obj).foo; obj }

    # Do the same thing except also create an expectation on .new
    mock.proxy(MyClass).new {|obj| stub(obj).foo; obj }
  

Class instances

    # Stub a method on an instance of MyClass when it is created
    any_instance_of(MyClass) do |klass|
      stub(klass).foo { 'bar' }
    end

    # Another way to do this which gives you access to the instance itself
    stub.proxy(MyClass).new do |obj|
      stub(obj).foo { 'bar' }
    end