rspec-mocks 2.0.0.a1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. data/.document +5 -0
  2. data/.gitignore +6 -0
  3. data/License.txt +22 -0
  4. data/README.markdown +8 -0
  5. data/Rakefile +50 -0
  6. data/VERSION +1 -0
  7. data/VERSION.yml +5 -0
  8. data/lib/rspec/mocks.rb +201 -0
  9. data/lib/rspec/mocks/argument_expectation.rb +51 -0
  10. data/lib/rspec/mocks/argument_matchers.rb +233 -0
  11. data/lib/rspec/mocks/error_generator.rb +81 -0
  12. data/lib/rspec/mocks/errors.rb +10 -0
  13. data/lib/rspec/mocks/extensions.rb +1 -0
  14. data/lib/rspec/mocks/extensions/object.rb +3 -0
  15. data/lib/rspec/mocks/framework.rb +15 -0
  16. data/lib/rspec/mocks/message_expectation.rb +326 -0
  17. data/lib/rspec/mocks/methods.rb +63 -0
  18. data/lib/rspec/mocks/mock.rb +65 -0
  19. data/lib/rspec/mocks/order_group.rb +29 -0
  20. data/lib/rspec/mocks/proxy.rb +230 -0
  21. data/lib/rspec/mocks/space.rb +28 -0
  22. data/lib/rspec/mocks/spec_methods.rb +39 -0
  23. data/lib/spec/mocks.rb +1 -0
  24. data/spec/rspec/mocks/any_number_of_times_spec.rb +36 -0
  25. data/spec/rspec/mocks/argument_expectation_spec.rb +23 -0
  26. data/spec/rspec/mocks/at_least_spec.rb +97 -0
  27. data/spec/rspec/mocks/at_most_spec.rb +93 -0
  28. data/spec/rspec/mocks/bug_report_10260_spec.rb +8 -0
  29. data/spec/rspec/mocks/bug_report_10263_spec.rb +27 -0
  30. data/spec/rspec/mocks/bug_report_11545_spec.rb +32 -0
  31. data/spec/rspec/mocks/bug_report_15719_spec.rb +29 -0
  32. data/spec/rspec/mocks/bug_report_496_spec.rb +17 -0
  33. data/spec/rspec/mocks/bug_report_600_spec.rb +22 -0
  34. data/spec/rspec/mocks/bug_report_7611_spec.rb +19 -0
  35. data/spec/rspec/mocks/bug_report_7805_spec.rb +22 -0
  36. data/spec/rspec/mocks/bug_report_8165_spec.rb +31 -0
  37. data/spec/rspec/mocks/bug_report_8302_spec.rb +26 -0
  38. data/spec/rspec/mocks/bug_report_830_spec.rb +21 -0
  39. data/spec/rspec/mocks/failing_argument_matchers_spec.rb +95 -0
  40. data/spec/rspec/mocks/hash_including_matcher_spec.rb +90 -0
  41. data/spec/rspec/mocks/hash_not_including_matcher_spec.rb +67 -0
  42. data/spec/rspec/mocks/mock_ordering_spec.rb +94 -0
  43. data/spec/rspec/mocks/mock_space_spec.rb +54 -0
  44. data/spec/rspec/mocks/mock_spec.rb +583 -0
  45. data/spec/rspec/mocks/multiple_return_value_spec.rb +113 -0
  46. data/spec/rspec/mocks/nil_expectation_warning_spec.rb +63 -0
  47. data/spec/rspec/mocks/null_object_mock_spec.rb +54 -0
  48. data/spec/rspec/mocks/once_counts_spec.rb +53 -0
  49. data/spec/rspec/mocks/options_hash_spec.rb +35 -0
  50. data/spec/rspec/mocks/partial_mock_spec.rb +164 -0
  51. data/spec/rspec/mocks/partial_mock_using_mocks_directly_spec.rb +66 -0
  52. data/spec/rspec/mocks/passing_argument_matchers_spec.rb +145 -0
  53. data/spec/rspec/mocks/precise_counts_spec.rb +52 -0
  54. data/spec/rspec/mocks/record_messages_spec.rb +26 -0
  55. data/spec/rspec/mocks/stub_chain_spec.rb +34 -0
  56. data/spec/rspec/mocks/stub_implementation_spec.rb +31 -0
  57. data/spec/rspec/mocks/stub_spec.rb +198 -0
  58. data/spec/rspec/mocks/stubbed_message_expectations_spec.rb +26 -0
  59. data/spec/rspec/mocks/twice_counts_spec.rb +67 -0
  60. data/spec/spec_helper.rb +52 -0
  61. data/spec/support/macros.rb +29 -0
  62. metadata +172 -0
@@ -0,0 +1,95 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+
3
+ module Rspec
4
+ module Mocks
5
+ describe "failing MockArgumentMatchers" do
6
+ before(:each) do
7
+ @mock = mock("test mock")
8
+ @reporter = Mock.new("reporter", :null_object => true)
9
+ end
10
+
11
+ after(:each) do
12
+ @mock.rspec_reset
13
+ end
14
+
15
+ it "should reject non boolean" do
16
+ @mock.should_receive(:random_call).with(boolean())
17
+ lambda do
18
+ @mock.random_call("false")
19
+ end.should raise_error(MockExpectationError)
20
+ end
21
+
22
+ it "should reject non numeric" do
23
+ @mock.should_receive(:random_call).with(an_instance_of(Numeric))
24
+ lambda do
25
+ @mock.random_call("1")
26
+ end.should raise_error(MockExpectationError)
27
+ end
28
+
29
+ it "should reject non string" do
30
+ @mock.should_receive(:random_call).with(an_instance_of(String))
31
+ lambda do
32
+ @mock.random_call(123)
33
+ end.should raise_error(MockExpectationError)
34
+ end
35
+
36
+ it "should reject goose when expecting a duck" do
37
+ @mock.should_receive(:random_call).with(duck_type(:abs, :div))
38
+ lambda { @mock.random_call("I don't respond to :abs or :div") }.should raise_error(MockExpectationError)
39
+ end
40
+
41
+ it "should fail if regexp does not match submitted string" do
42
+ @mock.should_receive(:random_call).with(/bcd/)
43
+ lambda { @mock.random_call("abc") }.should raise_error(MockExpectationError)
44
+ end
45
+
46
+ it "should fail if regexp does not match submitted regexp" do
47
+ @mock.should_receive(:random_call).with(/bcd/)
48
+ lambda { @mock.random_call(/bcde/) }.should raise_error(MockExpectationError)
49
+ end
50
+
51
+ it "should fail for a hash w/ wrong values" do
52
+ @mock.should_receive(:random_call).with(:a => "b", :c => "d")
53
+ lambda do
54
+ @mock.random_call(:a => "b", :c => "e")
55
+ end.should raise_error(MockExpectationError, /Mock 'test mock' expected :random_call with \(\{(:a=>\"b\", :c=>\"d\"|:c=>\"d\", :a=>\"b\")\}\) but received it with \(\{(:a=>\"b\", :c=>\"e\"|:c=>\"e\", :a=>\"b\")\}\)/)
56
+ end
57
+
58
+ it "should fail for a hash w/ wrong keys" do
59
+ @mock.should_receive(:random_call).with(:a => "b", :c => "d")
60
+ lambda do
61
+ @mock.random_call("a" => "b", "c" => "d")
62
+ end.should raise_error(MockExpectationError, /Mock 'test mock' expected :random_call with \(\{(:a=>\"b\", :c=>\"d\"|:c=>\"d\", :a=>\"b\")\}\) but received it with \(\{(\"a\"=>\"b\", \"c\"=>\"d\"|\"c\"=>\"d\", \"a\"=>\"b\")\}\)/)
63
+ end
64
+
65
+ it "should match against a Matcher" do
66
+ lambda do
67
+ @mock.should_receive(:msg).with(equal(3))
68
+ @mock.msg(37)
69
+ end.should raise_error(MockExpectationError, "Mock 'test mock' expected :msg with (equal 3) but received it with (37)")
70
+ end
71
+
72
+ it "should fail no_args with one arg" do
73
+ lambda do
74
+ @mock.should_receive(:msg).with(no_args)
75
+ @mock.msg(37)
76
+ end.should raise_error(MockExpectationError, "Mock 'test mock' expected :msg with (no args) but received it with (37)")
77
+ end
78
+
79
+ it "should fail hash_including with missing key" do
80
+ lambda do
81
+ @mock.should_receive(:msg).with(hash_including(:a => 1))
82
+ @mock.msg({})
83
+ end.should raise_error(MockExpectationError, "Mock 'test mock' expected :msg with (hash_including(:a=>1)) but received it with ({})")
84
+ end
85
+
86
+ it "should fail with block matchers" do
87
+ lambda do
88
+ @mock.should_receive(:msg).with {|arg| arg.should == :received }
89
+ @mock.msg :no_msg_for_you
90
+ end.should raise_error(Rspec::Expectations::ExpectationNotMetError, /expected: :received.*\s*.*got: :no_msg_for_you/)
91
+ end
92
+
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,90 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+
3
+ module Rspec
4
+ module Mocks
5
+ module ArgumentMatchers
6
+ describe HashIncludingMatcher do
7
+
8
+ it "should describe itself properly" do
9
+ HashIncludingMatcher.new(:a => 1).description.should == "hash_including(:a=>1)"
10
+ end
11
+
12
+ describe "passing" do
13
+ it "should match the same hash" do
14
+ hash_including(:a => 1).should == {:a => 1}
15
+ end
16
+
17
+ it "should match a hash with extra stuff" do
18
+ hash_including(:a => 1).should == {:a => 1, :b => 2}
19
+ end
20
+
21
+ describe "when matching against other matchers" do
22
+ it "should match an int against anything()" do
23
+ hash_including(:a => anything, :b => 2).should == {:a => 1, :b => 2}
24
+ end
25
+
26
+ it "should match a string against anything()" do
27
+ hash_including(:a => anything, :b => 2).should == {:a => "1", :b => 2}
28
+ end
29
+ end
30
+
31
+ describe "when passed only keys or keys mixed with key/value pairs" do
32
+ it "should match if the key is present" do
33
+ hash_including(:a).should == {:a => 1, :b => 2}
34
+ end
35
+
36
+ it "should match if more keys are present" do
37
+ hash_including(:a, :b).should == {:a => 1, :b => 2, :c => 3}
38
+ end
39
+
40
+ it "should match a string against a given key" do
41
+ hash_including(:a).should == {:a => "1", :b => 2}
42
+ end
43
+
44
+ it "should match if passed one key and one key/value pair" do
45
+ hash_including(:a, :b => 2).should == {:a => 1, :b => 2}
46
+ end
47
+
48
+ it "should match if passed many keys and one key/value pair" do
49
+ hash_including(:a, :b, :c => 3).should == {:a => 1, :b => 2, :c => 3, :d => 4}
50
+ end
51
+
52
+ it "should match if passed many keys and many key/value pairs" do
53
+ hash_including(:a, :b, :c => 3, :e => 5).should == {:a => 1, :b => 2, :c => 3, :d => 4, :e => 5}
54
+ end
55
+ end
56
+ end
57
+
58
+ describe "failing" do
59
+ it "should not match a non-hash" do
60
+ hash_including(:a => 1).should_not == 1
61
+ end
62
+
63
+ it "should not match a hash with a missing key" do
64
+ hash_including(:a => 1).should_not == {:b => 2}
65
+ end
66
+
67
+ it "should not match a hash with a missing key" do
68
+ hash_including(:a).should_not == {:b => 2}
69
+ end
70
+
71
+ it "should not match an empty hash with a given key" do
72
+ hash_including(:a).should_not == {}
73
+ end
74
+
75
+ it "should not match a hash with a missing key when one pair is matching" do
76
+ hash_including(:a, :b => 2).should_not == {:b => 2}
77
+ end
78
+
79
+ it "should not match a hash with an incorrect value" do
80
+ hash_including(:a => 1, :b => 2).should_not == {:a => 1, :b => 3}
81
+ end
82
+
83
+ it "should not match when values are nil but keys are different" do
84
+ hash_including(:a => nil).should_not == {:b => nil}
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,67 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+
3
+ module Rspec
4
+ module Mocks
5
+ module ArgumentMatchers
6
+ describe HashNotIncludingMatcher do
7
+
8
+ it "should describe itself properly" do
9
+ HashNotIncludingMatcher.new(:a => 5).description.should == "hash_not_including(:a=>5)"
10
+ end
11
+
12
+ describe "passing" do
13
+ it "should match a hash without the specified key" do
14
+ hash_not_including(:c).should == {:a => 1, :b => 2}
15
+ end
16
+
17
+ it "should match a hash with the specified key, but different value" do
18
+ hash_not_including(:b => 3).should == {:a => 1, :b => 2}
19
+ end
20
+
21
+ it "should match a hash without the specified key, given as anything()" do
22
+ hash_not_including(:c => anything).should == {:a => 1, :b => 2}
23
+ end
24
+
25
+ it "should match an empty hash" do
26
+ hash_not_including(:a).should == {}
27
+ end
28
+
29
+ it "should match a hash without any of the specified keys" do
30
+ hash_not_including(:a, :b, :c).should == { :d => 7}
31
+ end
32
+
33
+ end
34
+
35
+ describe "failing" do
36
+ it "should not match a non-hash" do
37
+ hash_not_including(:a => 1).should_not == 1
38
+ end
39
+
40
+ it "should not match a hash with a specified key" do
41
+ hash_not_including(:b).should_not == {:b => 2}
42
+ end
43
+
44
+ it "should not match a hash with the specified key/value pair" do
45
+ hash_not_including(:b => 2).should_not == {:a => 1, :b => 2}
46
+ end
47
+
48
+ it "should not match a hash with the specified key" do
49
+ hash_not_including(:a, :b => 3).should_not == {:a => 1, :b => 2}
50
+ end
51
+
52
+ it "should not match a hash with one of the specified keys" do
53
+ hash_not_including(:a, :b).should_not == {:b => 2}
54
+ end
55
+
56
+ it "should not match a hash with some of the specified keys" do
57
+ hash_not_including(:a, :b, :c).should_not == {:a => 1, :b => 2}
58
+ end
59
+
60
+ it "should not match a hash with one key/value pair included" do
61
+ hash_not_including(:a, :b, :c, :d => 7).should_not == { :d => 7}
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,94 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ module Rspec
4
+ module Mocks
5
+
6
+ describe "Mock ordering" do
7
+
8
+ before do
9
+ @mock = mock("test mock")
10
+ end
11
+
12
+ after do
13
+ @mock.rspec_reset
14
+ end
15
+
16
+ it "should pass two calls in order" do
17
+ @mock.should_receive(:one).ordered
18
+ @mock.should_receive(:two).ordered
19
+ @mock.one
20
+ @mock.two
21
+ @mock.rspec_verify
22
+ end
23
+
24
+ it "should pass three calls in order" do
25
+ @mock.should_receive(:one).ordered
26
+ @mock.should_receive(:two).ordered
27
+ @mock.should_receive(:three).ordered
28
+ @mock.one
29
+ @mock.two
30
+ @mock.three
31
+ @mock.rspec_verify
32
+ end
33
+
34
+ it "should fail if second call comes first" do
35
+ @mock.should_receive(:one).ordered
36
+ @mock.should_receive(:two).ordered
37
+ lambda do
38
+ @mock.two
39
+ end.should raise_error(MockExpectationError, "Mock 'test mock' received :two out of order")
40
+ end
41
+
42
+ it "should fail if third call comes first" do
43
+ @mock.should_receive(:one).ordered
44
+ @mock.should_receive(:two).ordered
45
+ @mock.should_receive(:three).ordered
46
+ @mock.one
47
+ lambda do
48
+ @mock.three
49
+ end.should raise_error(MockExpectationError, "Mock 'test mock' received :three out of order")
50
+ end
51
+
52
+ it "should fail if third call comes second" do
53
+ @mock.should_receive(:one).ordered
54
+ @mock.should_receive(:two).ordered
55
+ @mock.should_receive(:three).ordered
56
+ @mock.one
57
+ lambda do
58
+ @mock.three
59
+ end.should raise_error(MockExpectationError, "Mock 'test mock' received :three out of order")
60
+ end
61
+
62
+ it "should ignore order of non ordered calls" do
63
+ @mock.should_receive(:ignored_0)
64
+ @mock.should_receive(:ordered_1).ordered
65
+ @mock.should_receive(:ignored_1)
66
+ @mock.should_receive(:ordered_2).ordered
67
+ @mock.should_receive(:ignored_2)
68
+ @mock.should_receive(:ignored_3)
69
+ @mock.should_receive(:ordered_3).ordered
70
+ @mock.should_receive(:ignored_4)
71
+ @mock.ignored_3
72
+ @mock.ordered_1
73
+ @mock.ignored_0
74
+ @mock.ordered_2
75
+ @mock.ignored_4
76
+ @mock.ignored_2
77
+ @mock.ordered_3
78
+ @mock.ignored_1
79
+ @mock.rspec_verify
80
+ end
81
+
82
+ it "should pass when duplicates exist" do
83
+ @mock.should_receive(:a).ordered
84
+ @mock.should_receive(:b).ordered
85
+ @mock.should_receive(:a).ordered
86
+
87
+ @mock.a
88
+ @mock.b
89
+ @mock.a
90
+ end
91
+
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,54 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper.rb'
2
+ require 'rspec/mocks'
3
+
4
+ module Rspec
5
+ module Mocks
6
+ describe Space do
7
+ before :each do
8
+ @space = Space.new
9
+ klazz = Class.new do
10
+ def rspec_verify
11
+ @verified = true
12
+ end
13
+ def verified?
14
+ @verified
15
+ end
16
+ def rspec_reset
17
+ @reset = true
18
+ end
19
+ def reset?
20
+ @reset
21
+ end
22
+ end
23
+ @m1 = klazz.new
24
+ @m2 = klazz.new
25
+ end
26
+ it "should verify all mocks within" do
27
+ @space.add(@m1)
28
+ @space.add(@m2)
29
+ @space.verify_all
30
+ @m1.should be_verified
31
+ @m2.should be_verified
32
+ end
33
+ it "should reset all mocks within" do
34
+ @space.add(m1 = mock("mock1"))
35
+ @space.add(m2 = mock("mock2"))
36
+ m1.should_receive(:rspec_reset)
37
+ m2.should_receive(:rspec_reset)
38
+ @space.reset_all
39
+ end
40
+ it "should clear internal mocks on reset_all" do
41
+ @space.add(m = mock("mock"))
42
+ @space.reset_all
43
+ @space.instance_eval { mocks.empty? }.should be_true
44
+ end
45
+ it "should only add an instance once" do
46
+ @space.add(m1 = mock("mock1"))
47
+ @space.add(m1)
48
+ m1.should_receive(:rspec_verify)
49
+ @space.verify_all
50
+ end
51
+ end
52
+ end
53
+ end
54
+
@@ -0,0 +1,583 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ module Rspec
4
+ module Mocks
5
+ describe Mock do
6
+ treats_method_missing_as_private :subject => Mock.new, :noop => false
7
+
8
+ before(:each) do
9
+ @mock = mock("test mock")
10
+ end
11
+
12
+ after(:each) do
13
+ @mock.rspec_reset
14
+ end
15
+
16
+ it "should report line number of expectation of unreceived message" do
17
+ expected_error_line = __LINE__; @mock.should_receive(:wont_happen).with("x", 3)
18
+ begin
19
+ @mock.rspec_verify
20
+ violated
21
+ rescue MockExpectationError => e
22
+ # NOTE - this regexp ended w/ $, but jruby adds extra info at the end of the line
23
+ e.backtrace[0].should match(/#{File.basename(__FILE__)}:#{expected_error_line}/)
24
+ end
25
+ end
26
+
27
+ it "should report line number of expectation of unreceived message after #should_receive after similar stub" do
28
+ @mock.stub!(:wont_happen)
29
+ expected_error_line = __LINE__; @mock.should_receive(:wont_happen).with("x", 3)
30
+ begin
31
+ @mock.rspec_verify
32
+ violated
33
+ rescue MockExpectationError => e
34
+ # NOTE - this regexp ended w/ $, but jruby adds extra info at the end of the line
35
+ e.backtrace[0].should match(/#{File.basename(__FILE__)}:#{expected_error_line}/)
36
+ end
37
+ end
38
+
39
+ it "should pass when not receiving message specified as not to be received" do
40
+ @mock.should_not_receive(:not_expected)
41
+ @mock.rspec_verify
42
+ end
43
+
44
+ it "should pass when receiving message specified as not to be received with different args" do
45
+ @mock.should_not_receive(:message).with("unwanted text")
46
+ @mock.should_receive(:message).with("other text")
47
+ @mock.message "other text"
48
+ @mock.rspec_verify
49
+ end
50
+
51
+ it "should fail when receiving message specified as not to be received" do
52
+ @mock.should_not_receive(:not_expected)
53
+ lambda {
54
+ @mock.not_expected
55
+ violated
56
+ }.should raise_error(MockExpectationError, "Mock 'test mock' expected :not_expected with (no args) 0 times, but received it once")
57
+ end
58
+
59
+ it "should fail when receiving message specified as not to be received with args" do
60
+ @mock.should_not_receive(:not_expected).with("unexpected text")
61
+ lambda {
62
+ @mock.not_expected("unexpected text")
63
+ violated
64
+ }.should raise_error(MockExpectationError, "Mock 'test mock' expected :not_expected with (\"unexpected text\") 0 times, but received it once")
65
+ end
66
+
67
+ it "should pass when receiving message specified as not to be received with wrong args" do
68
+ @mock.should_not_receive(:not_expected).with("unexpected text")
69
+ @mock.not_expected "really unexpected text"
70
+ @mock.rspec_verify
71
+ end
72
+
73
+ it "should allow block to calculate return values" do
74
+ @mock.should_receive(:something).with("a","b","c").and_return { |a,b,c| c+b+a }
75
+ @mock.something("a","b","c").should == "cba"
76
+ @mock.rspec_verify
77
+ end
78
+
79
+ it "should allow parameter as return value" do
80
+ @mock.should_receive(:something).with("a","b","c").and_return("booh")
81
+ @mock.something("a","b","c").should == "booh"
82
+ @mock.rspec_verify
83
+ end
84
+
85
+ it "should return nil if no return value set" do
86
+ @mock.should_receive(:something).with("a","b","c")
87
+ @mock.something("a","b","c").should be_nil
88
+ @mock.rspec_verify
89
+ end
90
+
91
+ it "should raise exception if args don't match when method called" do
92
+ @mock.should_receive(:something).with("a","b","c").and_return("booh")
93
+ lambda {
94
+ @mock.something("a","d","c")
95
+ violated
96
+ }.should raise_error(MockExpectationError, "Mock 'test mock' expected :something with (\"a\", \"b\", \"c\") but received it with (\"a\", \"d\", \"c\")")
97
+ end
98
+
99
+ it "should raise exception if args don't match when method called even when the method is stubbed" do
100
+ @mock.stub!(:something)
101
+ @mock.should_receive(:something).with("a","b","c")
102
+ lambda {
103
+ @mock.something("a","d","c")
104
+ @mock.rspec_verify
105
+ }.should raise_error(MockExpectationError, "Mock 'test mock' expected :something with (\"a\", \"b\", \"c\") but received it with ([\"a\", \"d\", \"c\"])")
106
+ end
107
+
108
+ it "should raise exception if args don't match when method called even when using null_object" do
109
+ @mock = mock("test mock", :null_object => true)
110
+ @mock.should_receive(:something).with("a","b","c")
111
+ lambda {
112
+ @mock.something("a","d","c")
113
+ @mock.rspec_verify
114
+ }.should raise_error(MockExpectationError, "Mock 'test mock' expected :something with (\"a\", \"b\", \"c\") but received it with ([\"a\", \"d\", \"c\"])")
115
+ end
116
+
117
+ it "should fail if unexpected method called" do
118
+ lambda {
119
+ @mock.something("a","b","c")
120
+ violated
121
+ }.should raise_error(MockExpectationError, "Mock 'test mock' received unexpected message :something with (\"a\", \"b\", \"c\")")
122
+ end
123
+
124
+ it "should use block for expectation if provided" do
125
+ @mock.should_receive(:something) do | a, b |
126
+ a.should == "a"
127
+ b.should == "b"
128
+ "booh"
129
+ end
130
+ @mock.something("a", "b").should == "booh"
131
+ @mock.rspec_verify
132
+ end
133
+
134
+ it "should fail if expectation block fails" do
135
+ @mock.should_receive(:something) {| bool | bool.should be_true}
136
+ lambda {
137
+ @mock.something false
138
+ }.should raise_error(MockExpectationError, /Mock 'test mock' received :something but passed block failed with: expected true, got false/)
139
+ end
140
+
141
+ it "should fail right away when method defined as never is received" do
142
+ @mock.should_receive(:not_expected).never
143
+ lambda {
144
+ @mock.not_expected
145
+ }.should raise_error(MockExpectationError, "Mock 'test mock' expected :not_expected with (no args) 0 times, but received it once")
146
+ end
147
+
148
+ it "should eventually fail when method defined as never is received" do
149
+ @mock.should_receive(:not_expected).never
150
+ lambda {
151
+ @mock.not_expected
152
+ }.should raise_error(MockExpectationError, "Mock 'test mock' expected :not_expected with (no args) 0 times, but received it once")
153
+ end
154
+
155
+ it "should raise when told to" do
156
+ @mock.should_receive(:something).and_raise(RuntimeError)
157
+ lambda do
158
+ @mock.something
159
+ end.should raise_error(RuntimeError)
160
+ end
161
+
162
+ it "should raise passed an Exception instance" do
163
+ error = RuntimeError.new("error message")
164
+ @mock.should_receive(:something).and_raise(error)
165
+ lambda {
166
+ @mock.something
167
+ }.should raise_error(RuntimeError, "error message")
168
+ end
169
+
170
+ it "should raise RuntimeError with passed message" do
171
+ @mock.should_receive(:something).and_raise("error message")
172
+ lambda {
173
+ @mock.something
174
+ }.should raise_error(RuntimeError, "error message")
175
+ end
176
+
177
+ it "should not raise when told to if args dont match" do
178
+ @mock.should_receive(:something).with(2).and_raise(RuntimeError)
179
+ lambda {
180
+ @mock.something 1
181
+ }.should raise_error(MockExpectationError)
182
+ end
183
+
184
+ it "should throw when told to" do
185
+ @mock.should_receive(:something).and_throw(:blech)
186
+ lambda {
187
+ @mock.something
188
+ }.should throw_symbol(:blech)
189
+ end
190
+
191
+ it "should raise when explicit return and block constrained" do
192
+ lambda {
193
+ @mock.should_receive(:fruit) do |colour|
194
+ :strawberry
195
+ end.and_return :apple
196
+ }.should raise_error(AmbiguousReturnError)
197
+ end
198
+
199
+ it "should ignore args on any args" do
200
+ @mock.should_receive(:something).at_least(:once).with(any_args)
201
+ @mock.something
202
+ @mock.something 1
203
+ @mock.something "a", 2
204
+ @mock.something [], {}, "joe", 7
205
+ @mock.rspec_verify
206
+ end
207
+
208
+ it "should fail on no args if any args received" do
209
+ @mock.should_receive(:something).with(no_args())
210
+ lambda {
211
+ @mock.something 1
212
+ }.should raise_error(MockExpectationError, "Mock 'test mock' expected :something with (no args) but received it with (1)")
213
+ end
214
+
215
+ it "should fail when args are expected but none are received" do
216
+ @mock.should_receive(:something).with(1)
217
+ lambda {
218
+ @mock.something
219
+ }.should raise_error(MockExpectationError, "Mock 'test mock' expected :something with (1) but received it with (no args)")
220
+ end
221
+
222
+ it "should return value from block by default" do
223
+ @mock.stub!(:method_that_yields).and_yield
224
+ @mock.method_that_yields { :returned_obj }.should == :returned_obj
225
+ @mock.rspec_verify
226
+ end
227
+
228
+ it "should yield 0 args to blocks that take a variable number of arguments" do
229
+ @mock.should_receive(:yield_back).with(no_args()).once.and_yield
230
+ a = nil
231
+ @mock.yield_back {|*x| a = x}
232
+ a.should == []
233
+ @mock.rspec_verify
234
+ end
235
+
236
+ it "should yield 0 args multiple times to blocks that take a variable number of arguments" do
237
+ @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield.
238
+ and_yield
239
+ a = nil
240
+ b = []
241
+ @mock.yield_back {|*a| b << a}
242
+ b.should == [ [], [] ]
243
+ @mock.rspec_verify
244
+ end
245
+
246
+ it "should yield one arg to blocks that take a variable number of arguments" do
247
+ @mock.should_receive(:yield_back).with(no_args()).once.and_yield(99)
248
+ a = nil
249
+ @mock.yield_back {|*x| a = x}
250
+ a.should == [99]
251
+ @mock.rspec_verify
252
+ end
253
+
254
+ it "should yield one arg 3 times consecutively to blocks that take a variable number of arguments" do
255
+ @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield(99).
256
+ and_yield(43).
257
+ and_yield("something fruity")
258
+ a = nil
259
+ b = []
260
+ @mock.yield_back {|*a| b << a}
261
+ b.should == [[99], [43], ["something fruity"]]
262
+ @mock.rspec_verify
263
+ end
264
+
265
+ it "should yield many args to blocks that take a variable number of arguments" do
266
+ @mock.should_receive(:yield_back).with(no_args()).once.and_yield(99, 27, "go")
267
+ a = nil
268
+ @mock.yield_back {|*x| a = x}
269
+ a.should == [99, 27, "go"]
270
+ @mock.rspec_verify
271
+ end
272
+
273
+ it "should yield many args 3 times consecutively to blocks that take a variable number of arguments" do
274
+ @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield(99, :green, "go").
275
+ and_yield("wait", :amber).
276
+ and_yield("stop", 12, :red)
277
+ a = nil
278
+ b = []
279
+ @mock.yield_back {|*a| b << a}
280
+ b.should == [[99, :green, "go"], ["wait", :amber], ["stop", 12, :red]]
281
+ @mock.rspec_verify
282
+ end
283
+
284
+ it "should yield single value" do
285
+ @mock.should_receive(:yield_back).with(no_args()).once.and_yield(99)
286
+ a = nil
287
+ @mock.yield_back {|x| a = x}
288
+ a.should == 99
289
+ @mock.rspec_verify
290
+ end
291
+
292
+ it "should yield single value 3 times consecutively" do
293
+ @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield(99).
294
+ and_yield(43).
295
+ and_yield("something fruity")
296
+ a = nil
297
+ b = []
298
+ @mock.yield_back {|a| b << a}
299
+ b.should == [99, 43, "something fruity"]
300
+ @mock.rspec_verify
301
+ end
302
+
303
+ it "should yield two values" do
304
+ @mock.should_receive(:yield_back).with(no_args()).once.and_yield('wha', 'zup')
305
+ a, b = nil
306
+ @mock.yield_back {|x,y| a=x; b=y}
307
+ a.should == 'wha'
308
+ b.should == 'zup'
309
+ @mock.rspec_verify
310
+ end
311
+
312
+ it "should yield two values 3 times consecutively" do
313
+ @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield('wha', 'zup').
314
+ and_yield('not', 'down').
315
+ and_yield(14, 65)
316
+ a, b = nil
317
+ c = []
318
+ @mock.yield_back {|a,b| c << [a, b]}
319
+ c.should == [['wha', 'zup'], ['not', 'down'], [14, 65]]
320
+ @mock.rspec_verify
321
+ end
322
+
323
+ it "should fail when calling yielding method with wrong arity" do
324
+ @mock.should_receive(:yield_back).with(no_args()).once.and_yield('wha', 'zup')
325
+ lambda {
326
+ @mock.yield_back {|a|}
327
+ }.should raise_error(MockExpectationError, "Mock 'test mock' yielded |\"wha\", \"zup\"| to block with arity of 1")
328
+ end
329
+
330
+ it "should fail when calling yielding method consecutively with wrong arity" do
331
+ @mock.should_receive(:yield_back).once.with(no_args()).once.and_yield('wha', 'zup').
332
+ and_yield('down').
333
+ and_yield(14, 65)
334
+ lambda {
335
+ a, b = nil
336
+ c = []
337
+ @mock.yield_back {|a,b| c << [a, b]}
338
+ }.should raise_error(MockExpectationError, "Mock 'test mock' yielded |\"down\"| to block with arity of 2")
339
+ end
340
+
341
+ it "should fail when calling yielding method without block" do
342
+ @mock.should_receive(:yield_back).with(no_args()).once.and_yield('wha', 'zup')
343
+ lambda {
344
+ @mock.yield_back
345
+ }.should raise_error(MockExpectationError, "Mock 'test mock' asked to yield |[\"wha\", \"zup\"]| but no block was passed")
346
+ end
347
+
348
+ it "should be able to mock send" do
349
+ @mock.should_receive(:send).with(any_args)
350
+ @mock.send 'hi'
351
+ @mock.rspec_verify
352
+ end
353
+
354
+ it "should be able to raise from method calling yielding mock" do
355
+ @mock.should_receive(:yield_me).and_yield 44
356
+
357
+ lambda {
358
+ @mock.yield_me do |x|
359
+ raise "Bang"
360
+ end
361
+ }.should raise_error(StandardError, "Bang")
362
+
363
+ @mock.rspec_verify
364
+ end
365
+
366
+ it "should clear expectations after verify" do
367
+ @mock.should_receive(:foobar)
368
+ @mock.foobar
369
+ @mock.rspec_verify
370
+ lambda {
371
+ @mock.foobar
372
+ }.should raise_error(MockExpectationError, "Mock 'test mock' received unexpected message :foobar with (no args)")
373
+ end
374
+
375
+ it "should restore objects to their original state on rspec_reset" do
376
+ mock = mock("this is a mock")
377
+ mock.should_receive(:blah)
378
+ mock.rspec_reset
379
+ mock.rspec_verify #should throw if reset didn't work
380
+ end
381
+
382
+ it "should work even after method_missing starts raising NameErrors instead of NoMethodErrors" do
383
+ # Object#method_missing throws either NameErrors or NoMethodErrors.
384
+ #
385
+ # On a fresh ruby program Object#method_missing:
386
+ # * raises a NoMethodError when called directly
387
+ # * raises a NameError when called indirectly
388
+ #
389
+ # Once Object#method_missing has been called at least once (on any object)
390
+ # it starts behaving differently:
391
+ # * raises a NameError when called directly
392
+ # * raises a NameError when called indirectly
393
+ #
394
+ # There was a bug in Mock#method_missing that relied on the fact
395
+ # that calling Object#method_missing directly raises a NoMethodError.
396
+ # This example tests that the bug doesn't exist anymore.
397
+
398
+
399
+ # Ensures that method_missing always raises NameErrors.
400
+ a_method_that_doesnt_exist rescue
401
+
402
+
403
+ @mock.should_receive(:foobar)
404
+ @mock.foobar
405
+ @mock.rspec_verify
406
+
407
+ lambda { @mock.foobar }.should_not raise_error(NameError)
408
+ lambda { @mock.foobar }.should raise_error(MockExpectationError)
409
+ end
410
+
411
+ it "should temporarily replace a method stub on a mock" do
412
+ @mock.stub!(:msg).and_return(:stub_value)
413
+ @mock.should_receive(:msg).with(:arg).and_return(:mock_value)
414
+ @mock.msg(:arg).should equal(:mock_value)
415
+ @mock.msg.should equal(:stub_value)
416
+ @mock.msg.should equal(:stub_value)
417
+ @mock.rspec_verify
418
+ end
419
+
420
+ it "should not require a different signature to replace a method stub" do
421
+ @mock.stub!(:msg).and_return(:stub_value)
422
+ @mock.should_receive(:msg).and_return(:mock_value)
423
+ @mock.msg(:arg).should equal(:mock_value)
424
+ @mock.msg.should equal(:stub_value)
425
+ @mock.msg.should equal(:stub_value)
426
+ @mock.rspec_verify
427
+ end
428
+
429
+ it "should raise an error when a previously stubbed method has a negative expectation" do
430
+ @mock.stub!(:msg).and_return(:stub_value)
431
+ @mock.should_not_receive(:msg).and_return(:mock_value)
432
+ lambda {@mock.msg(:arg)}.should raise_error(MockExpectationError)
433
+ end
434
+
435
+ it "should temporarily replace a method stub on a non-mock" do
436
+ non_mock = Object.new
437
+ non_mock.stub!(:msg).and_return(:stub_value)
438
+ non_mock.should_receive(:msg).with(:arg).and_return(:mock_value)
439
+ non_mock.msg(:arg).should equal(:mock_value)
440
+ non_mock.msg.should equal(:stub_value)
441
+ non_mock.msg.should equal(:stub_value)
442
+ non_mock.rspec_verify
443
+ end
444
+
445
+ it "should return the stubbed value when no new value specified" do
446
+ @mock.stub!(:msg).and_return(:stub_value)
447
+ @mock.should_receive(:msg)
448
+ @mock.msg.should equal(:stub_value)
449
+ @mock.rspec_verify
450
+ end
451
+
452
+ it "should not mess with the stub's yielded values when also mocked" do
453
+ @mock.stub!(:yield_back).and_yield(:stub_value)
454
+ @mock.should_receive(:yield_back).and_yield(:mock_value)
455
+ @mock.yield_back{|v| v.should == :mock_value }
456
+ @mock.yield_back{|v| v.should == :stub_value }
457
+ @mock.rspec_verify
458
+ end
459
+
460
+ it "should yield multiple values after a similar stub" do
461
+ File.stub!(:open).and_yield(:stub_value)
462
+ File.should_receive(:open).and_yield(:first_call).and_yield(:second_call)
463
+ yielded_args = []
464
+ File.open {|v| yielded_args << v }
465
+ yielded_args.should == [:first_call, :second_call]
466
+ File.open {|v| v.should == :stub_value }
467
+ File.rspec_verify
468
+ end
469
+
470
+ it "should assign stub return values" do
471
+ mock = Mock.new('name', :message => :response)
472
+ mock.message.should == :response
473
+ end
474
+
475
+ end
476
+
477
+ describe "a mock message receiving a block" do
478
+ before(:each) do
479
+ @mock = mock("mock")
480
+ @calls = 0
481
+ end
482
+
483
+ def add_call
484
+ @calls = @calls + 1
485
+ end
486
+
487
+ it "should call the block after #should_receive" do
488
+ @mock.should_receive(:foo) { add_call }
489
+
490
+ @mock.foo
491
+
492
+ @calls.should == 1
493
+ end
494
+
495
+ it "should call the block after #should_receive after a similar stub" do
496
+ @mock.stub!(:foo).and_return(:bar)
497
+ @mock.should_receive(:foo) { add_call }
498
+
499
+ @mock.foo
500
+
501
+ @calls.should == 1
502
+ end
503
+
504
+ it "should call the block after #once" do
505
+ @mock.should_receive(:foo).once { add_call }
506
+
507
+ @mock.foo
508
+
509
+ @calls.should == 1
510
+ end
511
+
512
+ it "should call the block after #twice" do
513
+ @mock.should_receive(:foo).twice { add_call }
514
+
515
+ @mock.foo
516
+ @mock.foo
517
+
518
+ @calls.should == 2
519
+ end
520
+
521
+ it "should call the block after #times" do
522
+ @mock.should_receive(:foo).exactly(10).times { add_call }
523
+
524
+ (1..10).each { @mock.foo }
525
+
526
+ @calls.should == 10
527
+ end
528
+
529
+ it "should call the block after #any_number_of_times" do
530
+ @mock.should_receive(:foo).any_number_of_times { add_call }
531
+
532
+ (1..7).each { @mock.foo }
533
+
534
+ @calls.should == 7
535
+ end
536
+
537
+ it "should call the block after #ordered" do
538
+ @mock.should_receive(:foo).ordered { add_call }
539
+ @mock.should_receive(:bar).ordered { add_call }
540
+
541
+ @mock.foo
542
+ @mock.bar
543
+
544
+ @calls.should == 2
545
+ end
546
+ end
547
+
548
+ describe 'string representation generated by #to_s' do
549
+ it 'should not contain < because that might lead to invalid HTML in some situations' do
550
+ mock = mock("Dog")
551
+ valid_html_str = "#{mock}"
552
+ valid_html_str.should_not include('<')
553
+ end
554
+ end
555
+
556
+ describe "mock created with no name" do
557
+ it "should name itself 'mock'" do
558
+ mock.to_s.should include('mock')
559
+ end
560
+
561
+ it "should name itself after initially stubbed methods" do
562
+ string = mock(:foo => "woo", :bar => "car").to_s
563
+ string.should include('foo: \"woo\"', 'bar: \"car\"')
564
+ end
565
+
566
+ it "should respond to initially stubbed methods" do
567
+ mock = mock(:foo => "woo", :bar => "car")
568
+ mock.foo.should == "woo"
569
+ mock.bar.should == "car"
570
+ end
571
+ end
572
+
573
+ describe "==" do
574
+ it "sends '== self' to the comparison object" do
575
+ first = mock('first')
576
+ second = mock('second')
577
+
578
+ first.should_receive(:==).with(second)
579
+ second == first
580
+ end
581
+ end
582
+ end
583
+ end