Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Implemented test spies.

This allows you to establish a stub, then later verify it was received.

    object = Object.new
    object.stub!(:message)
    object.message
    object.should have_received(:message)   # passes
    object.should_not have_receive(:aieeee) # passes
    object.should have_received(:zomg)      # fails

[#906 state:resolved milestone:'Next Release']
  • Loading branch information...
commit da2c6113622ad960fdd69e5ff7b25e5679f2ba4b 1 parent 14761f8
@technicalpickles technicalpickles authored committed
View
1  History.rdoc
@@ -8,6 +8,7 @@
* Eric Meyer & David Chelimsky
* CTRL-C actually stops execution! (Bryan Helmkamp - #911)
* make drb port configurable (Chris Flipse - #875)
+ * added test spies (should_have_received) (Joshua Nichols - #906)
* bug fixes
* don't define top-level context() method when running in IRB (#899)
View
1  lib/spec/matchers.rb
@@ -12,6 +12,7 @@
require 'spec/matchers/errors'
require 'spec/matchers/exist'
require 'spec/matchers/generated_descriptions'
+require 'spec/matchers/have_received'
require 'spec/matchers/has'
require 'spec/matchers/have'
require 'spec/matchers/include'
View
24 lib/spec/matchers/have_received.rb
@@ -0,0 +1,24 @@
+module Spec
+ module Matchers
+ def have_received(sym, *args, &block)
+ Matcher.new :have_received, sym, args, block do |sym, args, block|
+ match do |actual|
+ actual.received_message?(sym, *args, &block)
+ end
+
+ failure_message_for_should do |actual|
+ "expected #{actual.inspect} to have received #{sym.inspect} with #{args.inspect}"
+ end
+
+ failure_message_for_should_not do |actual|
+ "expected #{actual.inspect} to not have received #{sym.inspect} with #{args.inspect}, but did"
+ end
+
+ description do
+ "to have received #{sym.inspect} with #{args.inspect}"
+ end
+ end
+ end
+ end
+end
+
View
1  lib/spec/mocks/proxy.rb
@@ -155,6 +155,7 @@ def define_expected_method(sym)
end
target_metaclass.class_eval(<<-EOF, __FILE__, __LINE__)
def #{sym}(*args, &block)
+ __mock_proxy.record_message_received(:#{sym}, args, block)
__mock_proxy.message_received :#{sym}, *args, &block
end
#{visibility_string}
View
61 spec/spec/matchers/have_received_spec.rb
@@ -0,0 +1,61 @@
+require 'spec/spec_helper'
+module Spec
+ module Matchers
+ describe "[object.should] have_received(method, *args)" do
+ before do
+ @object = String.new
+ end
+
+ it "does match if method is called with correct args" do
+ @object.stub!(:slice)
+ @object.slice(5)
+
+ have_received(:slice, 5).matches?(@object).should be_true
+ end
+
+ it "does not match if method is called with incorrect args" do
+ @object.stub!(:slice)
+ @object.slice(3)
+
+ have_received(:slice, 5).matches?(@object).should be_false
+ end
+
+ it "does not match if method is not called" do
+ @object.stub!(:slice)
+
+ have_received(:slice, 5).matches?(@object).should be_false
+ end
+
+ it "should describe itself" do
+ @object.stub!(:slice)
+ @object.slice(5)
+
+ matcher = have_received(:slice, 5)
+ matcher.matches?(@object)
+
+ matcher.description.should == "to have received :slice with [5]"
+ end
+
+ it "should provide failure message for should" do
+ @object.stub!(:slice)
+ @object.slice(5)
+
+ matcher = have_received(:slice, 5)
+ matcher.matches?(@object)
+
+ matcher.failure_message_for_should.should == %Q{expected "" to have received :slice with [5]}
+ end
+
+ it "should provide failure message for should not" do
+ @object.stub!(:slice)
+ @object.slice(5)
+
+ matcher = have_received(:slice, 5)
+ matcher.matches?(@object)
+
+ matcher.failure_message_for_should_not.should == %Q{expected "" to not have received :slice with [5], but did}
+ end
+ end
+
+ end
+end

1 comment on commit da2c611

@smtlaissezfaire

Sweet!

Does it work with the various mock expectations? Could we do something like this:

obj.should have_received(:foo).with("bar", "baz").twice

Please sign in to comment.
Something went wrong with that request. Please try again.