File: spys_test.rb

package info (click to toggle)
ruby-flexmock 3.0.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 836 kB
  • sloc: ruby: 7,572; makefile: 6
file content (215 lines) | stat: -rw-r--r-- 5,317 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
#!/usr/bin/env ruby

require 'test_helper'

class TestSpys < Minitest::Test
  include FlexMock::Minitest

  class FooBar
    def foo
      :foofoo
    end
    def bar
    end
  end

  def setup
    super
    @spy = flexmock(:on, FooBar)
  end

  def test_spy_detects_simple_call
    @spy.foo
    assert_spy_called @spy, :foo
  end

  def test_spy_detects_simple_call_ignoring_args
    @spy.foo(1)
    assert_spy_called @spy, :foo, :_
  end

  def test_spy_rejects_a_never_made_call
    @spy.foo
    assert_spy_not_called @spy, :bar
  end

  def test_spy_detects_call_with_literal_arg
    @spy.foo(1)
    assert_spy_called @spy, :foo, 1
  end

  def test_spy_detects_call_with_class_arg
    @spy.foo(1)
    assert_spy_called @spy, :foo, Integer
  end

  def test_spy_rejects_call_with_non_matching_literal_arg
    @spy.foo(2)
    assert_spy_not_called @spy, :foo, 1
  end

  def test_spy_detects_call_with_multiple_arguments
    @spy.foo(1, "HI", :foo)
    assert_spy_called @spy, :foo, /1/, "HI", Symbol
  end

  def test_spy_detects_multiple_calls_with_different_arguments
    @spy.foo(1)
    @spy.foo(1)
    assert_spy_called @spy, {:times => 2}, :foo, 1
  end

  def test_spy_rejects_if_times_options_not_matching
    @spy.foo(1)
    @spy.foo(1)
    assert_spy_not_called @spy, {:times => 1}, :foo, 1
  end

  def test_spy_detects_a_block
    @spy.foo { }
    assert_spy_called @spy, {:with_block => true}, :foo
  end

  def test_spy_rejects_a_block
    @spy.foo { }
    assert_spy_not_called @spy, {:with_block => false}, :foo
  end

  def test_spy_detects_a_missing_block
    @spy.foo
    assert_spy_called @spy, {:with_block => false}, :foo
  end

  def test_spy_rejects_a_missing_block
    @spy.foo
    assert_spy_not_called @spy, :foo, Proc
  end

  def test_spy_ignores_block
    @spy.foo { }
    assert_spy_called @spy, :foo
  end

  def test_spy_accepts_correct_additional_validations
    @spy.foo(2)
    is_even = proc { |n| assert_equal 0, n%2 }
    assert_spy_called @spy, { :and => is_even }, :foo, Integer
  end

  def test_spy_accepts_multiple_additional_validations_first_failing
    @spy.foo(4)
    is_two  = proc { |n| assert_equal 2, n }
    is_even = proc { |n| assert_equal 0, n%2 }
    assert_failed(/Expected: 2.*Actual: 4/mi) do
      assert_spy_called @spy, { :and => [is_two, is_even] }, :foo, Integer
    end
  end

  def test_spy_accepts_multiple_additional_validations_second_failing
    @spy.foo(4)
    is_even = proc { |n| assert_equal 0, n%2 }
    is_two  = proc { |n| assert_equal 2, n }
    assert_failed(/Expected: 2.*Actual: 4/mi) do
      assert_spy_called @spy, { :and => [is_even, is_two] }, :foo, Integer
    end
  end

  def test_spy_rejects_incorrect_additional_validations
    @spy.foo(3)
    is_even = proc { |n| assert_equal 0, n%2 }
    assert_failed(/Expected: 0.*Actual: 1/mi) do
      assert_spy_called @spy, { :and => is_even }, :foo, Integer
    end
  end

  def test_spy_selectively_applies_additional_validations
    @spy.foo(2)
    @spy.foo(3)
    @spy.foo(4)
    is_even = proc { |n| assert_equal 0, n%2 }
    assert_failed(/Expected: 0.*Actual: 1/mi) do
      assert_spy_called @spy, { :and => is_even, :on => 2 }, :foo, Integer
    end
  end

  def assert_failed(message_pattern)
    failed = false
    begin
      yield
    rescue assertion_failed_error => ex
      failed = true
      assert_match message_pattern, ex.message
    end
    assert(failed, "Expected block to fail")
  end

  def test_spy_methods_can_be_stubbed
    @spy.should_receive(:foo).and_return(:hi)
    result = @spy.foo
    assert_equal result, :hi
    assert_spy_called @spy, :foo
  end

  def test_spy_cannot_see_normal_methods
    foo = FooBar.new
    flexmock(foo)
    assert_equal :foofoo, foo.foo
    assert_spy_not_called foo, :foo
  end

  def test_spy_cannot_see_normal_methods2
    foo = FooBar.new
    flexmock(foo).should_receive(:foo).pass_thru
    assert_equal :foofoo, foo.foo
    assert_spy_called foo, :foo
  end

  def test_calling_non_spy_base_methods_is_an_error
    assert_raises(NoMethodError) do
      @spy.baz
    end
  end

  def test_cant_put_expectations_on_non_base_class_methodsx
    ex = assert_raises(NoMethodError) do
      @spy.should_receive(:baz).and_return(:bar)
    end
    assert_match(/cannot stub.*defined.*base.*class/i, ex.message)
    assert_match(/method: +baz/i, ex.message)
    assert_match(/base class: +TestSpys::FooBar/i, ex.message)
  end

  def test_cant_put_expectations_on_non_base_class_methods_unless_explicit
    @spy.should_receive(:baz).explicitly.and_return(:bar)
    @spy.baz
    assert_spy_called @spy, :baz
  end

  def test_ok_to_use_explicit_even_when_its_not_needed
    @spy.should_receive(:foo).explicitly.and_return(:bar)
    @spy.foo
    assert_spy_called @spy, :foo
  end

  def test_can_spy_on_partial_mocks
    @foo = FooBar.new
    @spy = flexmock(@foo)
    @foo.should_receive(:foo => :baz)
    result = @foo.foo
    assert_equal :baz, result
    assert_spy_called @foo, :foo
  end

  def test_can_spy_on_class_defined_methods
    flexmock(FooBar).should_receive(:new).and_return(:dummy)
    FooBar.new
    assert_spy_called FooBar, :new
  end

  def test_can_spy_on_regular_mocks
    mock = flexmock("regular mock")
    mock.should_receive(:foo => :bar)
    mock.foo
    assert_spy_called mock, :foo
  end
end