Permalink
Browse files

Mocks can return stubbed values

  • Loading branch information...
1 parent 61b3d5e commit 4e84c52034abd190f076fdb760efba8dbfec197f @txus committed Nov 13, 2010
View
@@ -12,7 +12,7 @@ development.
* Pretty decent reporter with colors
* Test doubles and stubs (no partial stubbing yet)
-* Mocks (message expectations)
+* Mocks (message expectations) with _optionally_ stubbable return values
* Nested example groups (declare them with either describe or context)
* Pending examples
* Matchers (use with object.must or object.must_not)
@@ -96,6 +96,31 @@ development.
string.reverse # Expectation fulfilled!
end
+ it "can be told the number of times it is expected" do
+ string = "my string"
+ string.expects(:reverse).once # or
+ string.expects(:reverse).twice # or
+ string.expects(:reverse).exactly(3).times
+
+ string.reverse # Fails!
+ end
+
+ it "can return a stubbed value" do
+ string = "my string"
+ string.expects(:reverse).and_returns 'stubbed value'
+
+ string.reverse # => "stubbed value"
+ end
+
+ it "can return a stubbed proc" do
+ string = "my string"
+ string.expects(:reverse).and_returns do
+ 3 + 4
+ end
+
+ string.reverse # => 7
+ end
+
it "is declared with does_not_expect in case it is negative" do
string = "my string"
string.does_not_expect(:reverse)
@@ -134,9 +159,12 @@ development.
Message expectation
* is declared with expects
+ * can be told the number of times it is expected [FAILED]
+ * can return a stubbed value
+ * can return a stubbed proc
* is declared with does_not_expect in case it is negative [FAILED]
- 13 examples, 3 failures, 2 pending
+ 16 examples, 4 failures, 2 pending
##Feedback
View
@@ -40,7 +40,7 @@ Feature: Mocks (message expectations)
end
"""
When I run "stendhal sample_spec.rb"
- # Then the exit status should be 0
+ Then the exit status should be 0
And the output should contain "3 examples, 1 failure"
And the output should contain "expected to be sent :foo 1 time, but received it 0 times"
@@ -140,7 +140,7 @@ Feature: Mocks (message expectations)
end
it "calls foo three times" do
object = MyClass.new
- object.expects(:foo).exactly(3).times.and_return('stubbed foo')
+ object.expects(:foo).exactly(3).times.and_returns('stubbed foo')
3.times { object.bar.must eq('stubbed foo') }
end
@@ -71,7 +71,6 @@ def initialize(method, options = {})
end
def register_call
- puts "#{@times_called}"
@times_called += 1
end
@@ -23,24 +23,42 @@ def #{method}(*args, &block)
end
def once
+ raise "This object has no mocks." unless @__verifier
__verifier.expectation_for(__verifier.last_mocked_method).times_expected = 1
self
end
def twice
+ raise "This object has no mocks." unless @__verifier
__verifier.expectation_for(__verifier.last_mocked_method).times_expected = 2
self
end
def exactly(times)
+ raise "This object has no mocks." unless @__verifier
__verifier.expectation_for(__verifier.last_mocked_method).times_expected = times
self
end
def times
+ raise "This object has no mocks." unless @__verifier
self
end
+ def and_returns(retval = nil, &block)
+ raise "This object has no mocks." unless @__verifier
+ method = __verifier.last_mocked_method
+ str = retval.to_s
+ unless respond_to?(:"__unstubbed_#{method}")
+ metaclass = (class << self;self;end)
+ metaclass.send(:alias_method, :"__unstubbed_#{method}", :"__original_#{method}")
+ metaclass.send(:undef_method, :"__original_#{method}")
+
+ return_value = block || Proc.new { retval }
+ metaclass.send(:define_method, :"__original_#{method}", return_value)
+ end
+ end
+
def does_not_expect(method)
expects(method, :negative => true)
end
@@ -15,7 +15,6 @@ def assign_stubs(stubs)
v
end
end
-
end
end
@@ -65,6 +65,11 @@ module Mocks
subject.send(:__verifier).stub(:last_mocked_method).and_return :length
subject.expects(:length).send(name).should be_a(MyArray)
end
+ it 'raises an error if called without a previous mock' do
+ expect {
+ subject.send(name)
+ }.to raise_error("This object has no mocks.")
+ end
end
end
@@ -82,15 +87,43 @@ module Mocks
subject.send(:__verifier).stub(:last_mocked_method).and_return :length
subject.expects(:length).twice.should be_a(MyArray)
end
+ it 'raises an error if called without a previous mock' do
+ expect {
+ subject.exactly(2)
+ }.to raise_error("This object has no mocks.")
+ end
end
describe "#times" do
it 'returns itself to allow chaining' do
subject.expects(:length).times.should be_a(MyArray)
end
+ it 'raises an error if called without a previous mock' do
+ expect {
+ subject.times
+ }.to raise_error("This object has no mocks.")
+ end
end
end
+
+ describe "#and_returns" do
+ it 'stubs the return value' do
+ subject.expects(:length).and_returns 5
+ subject.length.should == 5
+ end
+ it 'accepts a block as the return value' do
+ subject.expects(:length).and_returns do
+ 3 + 4
+ end
+ subject.length.should == 7
+ end
+ it 'saves the unstubbed method' do
+ subject.expects(:length).and_returns(:foo)
+ subject.should respond_to(:__unstubbed_length)
+ subject.send(:__unstubbed_length).should == 3
+ end
+ end
end
end
end

0 comments on commit 4e84c52

Please sign in to comment.