mocha 0.5.6 → 3.0.2

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 (192) hide show
  1. checksums.yaml +7 -0
  2. data/.gemtest +0 -0
  3. data/.github/FUNDING.yml +1 -0
  4. data/.rubocop.yml +92 -0
  5. data/.rubocop_todo.yml +39 -0
  6. data/.yardopts +25 -0
  7. data/CONTRIBUTING.md +7 -0
  8. data/COPYING.md +3 -0
  9. data/Gemfile +17 -0
  10. data/{MIT-LICENSE → MIT-LICENSE.md} +2 -2
  11. data/README.md +361 -0
  12. data/RELEASE.md +1235 -0
  13. data/Rakefile +165 -123
  14. data/gemfiles/Gemfile.minitest.latest +8 -0
  15. data/gemfiles/Gemfile.rubocop +9 -0
  16. data/gemfiles/Gemfile.test-unit.latest +8 -0
  17. data/lib/mocha/any_instance_method.rb +12 -26
  18. data/lib/mocha/any_instance_receiver.rb +20 -0
  19. data/lib/mocha/api.rb +213 -0
  20. data/lib/mocha/argument_iterator.rb +17 -0
  21. data/lib/mocha/backtrace_filter.rb +15 -0
  22. data/lib/mocha/block_matchers.rb +33 -0
  23. data/lib/mocha/cardinality.rb +110 -0
  24. data/lib/mocha/central.rb +33 -22
  25. data/lib/mocha/change_state_side_effect.rb +17 -0
  26. data/lib/mocha/class_methods.rb +67 -0
  27. data/lib/mocha/configuration.rb +338 -0
  28. data/lib/mocha/default_name.rb +15 -0
  29. data/lib/mocha/default_receiver.rb +13 -0
  30. data/lib/mocha/deprecation.rb +19 -14
  31. data/lib/mocha/detection/minitest.rb +25 -0
  32. data/lib/mocha/detection/test_unit.rb +30 -0
  33. data/lib/mocha/error_with_filtered_backtrace.rb +15 -0
  34. data/lib/mocha/exception_raiser.rb +11 -10
  35. data/lib/mocha/expectation.rb +553 -168
  36. data/lib/mocha/expectation_error.rb +9 -14
  37. data/lib/mocha/expectation_error_factory.rb +37 -0
  38. data/lib/mocha/expectation_list.rb +30 -14
  39. data/lib/mocha/hooks.rb +55 -0
  40. data/lib/mocha/ignoring_warning.rb +20 -0
  41. data/lib/mocha/impersonating_any_instance_name.rb +13 -0
  42. data/lib/mocha/impersonating_name.rb +13 -0
  43. data/lib/mocha/in_state_ordering_constraint.rb +17 -0
  44. data/lib/mocha/inspect.rb +56 -22
  45. data/lib/mocha/instance_method.rb +17 -4
  46. data/lib/mocha/integration/assertion_counter.rb +15 -0
  47. data/lib/mocha/integration/minitest/adapter.rb +71 -0
  48. data/lib/mocha/integration/minitest.rb +29 -0
  49. data/lib/mocha/integration/monkey_patcher.rb +26 -0
  50. data/lib/mocha/integration/test_unit/adapter.rb +61 -0
  51. data/lib/mocha/integration/test_unit.rb +29 -0
  52. data/lib/mocha/integration.rb +5 -0
  53. data/lib/mocha/invocation.rb +76 -0
  54. data/lib/mocha/logger.rb +13 -0
  55. data/lib/mocha/macos_version.rb +7 -0
  56. data/lib/mocha/method_matcher.rb +8 -10
  57. data/lib/mocha/minitest.rb +7 -0
  58. data/lib/mocha/mock.rb +333 -108
  59. data/lib/mocha/mockery.rb +199 -0
  60. data/lib/mocha/name.rb +13 -0
  61. data/lib/mocha/not_initialized_error.rb +9 -0
  62. data/lib/mocha/object_methods.rb +183 -0
  63. data/lib/mocha/object_receiver.rb +20 -0
  64. data/lib/mocha/parameter_matchers/all_of.rb +38 -28
  65. data/lib/mocha/parameter_matchers/any_of.rb +44 -33
  66. data/lib/mocha/parameter_matchers/any_parameters.rb +33 -26
  67. data/lib/mocha/parameter_matchers/anything.rb +31 -22
  68. data/lib/mocha/parameter_matchers/base_methods.rb +64 -0
  69. data/lib/mocha/parameter_matchers/equals.rb +36 -25
  70. data/lib/mocha/parameter_matchers/equivalent_uri.rb +65 -0
  71. data/lib/mocha/parameter_matchers/has_entries.rb +48 -29
  72. data/lib/mocha/parameter_matchers/has_entry.rb +90 -42
  73. data/lib/mocha/parameter_matchers/has_key.rb +39 -26
  74. data/lib/mocha/parameter_matchers/has_keys.rb +59 -0
  75. data/lib/mocha/parameter_matchers/has_value.rb +39 -26
  76. data/lib/mocha/parameter_matchers/includes.rb +88 -23
  77. data/lib/mocha/parameter_matchers/instance_methods.rb +28 -0
  78. data/lib/mocha/parameter_matchers/instance_of.rb +37 -26
  79. data/lib/mocha/parameter_matchers/is_a.rb +38 -26
  80. data/lib/mocha/parameter_matchers/kind_of.rb +39 -26
  81. data/lib/mocha/parameter_matchers/not.rb +37 -26
  82. data/lib/mocha/parameter_matchers/optionally.rb +52 -17
  83. data/lib/mocha/parameter_matchers/positional_or_keyword_hash.rb +91 -0
  84. data/lib/mocha/parameter_matchers/regexp_matches.rb +37 -25
  85. data/lib/mocha/parameter_matchers/responds_with.rb +82 -0
  86. data/lib/mocha/parameter_matchers/yaml_equivalent.rb +55 -0
  87. data/lib/mocha/parameter_matchers.rb +12 -5
  88. data/lib/mocha/parameters_matcher.rb +28 -19
  89. data/lib/mocha/raised_exception.rb +13 -0
  90. data/lib/mocha/return_values.rb +13 -18
  91. data/lib/mocha/ruby_version.rb +7 -0
  92. data/lib/mocha/sequence.rb +23 -17
  93. data/lib/mocha/single_return_value.rb +8 -18
  94. data/lib/mocha/state_machine.rb +95 -0
  95. data/lib/mocha/stubbed_method.rb +96 -0
  96. data/lib/mocha/stubbing_error.rb +10 -0
  97. data/lib/mocha/test_unit.rb +7 -0
  98. data/lib/mocha/thrower.rb +15 -0
  99. data/lib/mocha/thrown_object.rb +14 -0
  100. data/lib/mocha/version.rb +5 -0
  101. data/lib/mocha/yield_parameters.rb +12 -20
  102. data/lib/mocha.rb +19 -17
  103. data/mise.toml +2 -0
  104. data/mocha.gemspec +40 -0
  105. metadata +130 -145
  106. data/COPYING +0 -3
  107. data/README +0 -35
  108. data/RELEASE +0 -188
  109. data/examples/misc.rb +0 -44
  110. data/examples/mocha.rb +0 -26
  111. data/examples/stubba.rb +0 -65
  112. data/lib/mocha/auto_verify.rb +0 -118
  113. data/lib/mocha/class_method.rb +0 -66
  114. data/lib/mocha/infinite_range.rb +0 -25
  115. data/lib/mocha/is_a.rb +0 -9
  116. data/lib/mocha/metaclass.rb +0 -7
  117. data/lib/mocha/missing_expectation.rb +0 -17
  118. data/lib/mocha/multiple_yields.rb +0 -20
  119. data/lib/mocha/no_yields.rb +0 -11
  120. data/lib/mocha/object.rb +0 -110
  121. data/lib/mocha/parameter_matchers/base.rb +0 -15
  122. data/lib/mocha/parameter_matchers/object.rb +0 -9
  123. data/lib/mocha/pretty_parameters.rb +0 -28
  124. data/lib/mocha/setup_and_teardown.rb +0 -23
  125. data/lib/mocha/single_yield.rb +0 -18
  126. data/lib/mocha/standalone.rb +0 -32
  127. data/lib/mocha/stub.rb +0 -18
  128. data/lib/mocha/test_case_adapter.rb +0 -49
  129. data/lib/mocha_standalone.rb +0 -2
  130. data/lib/stubba.rb +0 -2
  131. data/test/acceptance/expected_invocation_count_acceptance_test.rb +0 -187
  132. data/test/acceptance/mocha_acceptance_test.rb +0 -98
  133. data/test/acceptance/mock_with_initializer_block_acceptance_test.rb +0 -44
  134. data/test/acceptance/mocked_methods_dispatch_acceptance_test.rb +0 -71
  135. data/test/acceptance/optional_parameters_acceptance_test.rb +0 -63
  136. data/test/acceptance/parameter_matcher_acceptance_test.rb +0 -117
  137. data/test/acceptance/partial_mocks_acceptance_test.rb +0 -40
  138. data/test/acceptance/sequence_acceptance_test.rb +0 -179
  139. data/test/acceptance/standalone_acceptance_test.rb +0 -131
  140. data/test/acceptance/stubba_acceptance_test.rb +0 -102
  141. data/test/active_record_test_case.rb +0 -36
  142. data/test/deprecation_disabler.rb +0 -15
  143. data/test/execution_point.rb +0 -34
  144. data/test/integration/mocha_test_result_integration_test.rb +0 -105
  145. data/test/integration/stubba_integration_test.rb +0 -89
  146. data/test/integration/stubba_test_result_integration_test.rb +0 -85
  147. data/test/method_definer.rb +0 -18
  148. data/test/test_helper.rb +0 -12
  149. data/test/test_runner.rb +0 -31
  150. data/test/unit/any_instance_method_test.rb +0 -126
  151. data/test/unit/array_inspect_test.rb +0 -16
  152. data/test/unit/auto_verify_test.rb +0 -129
  153. data/test/unit/central_test.rb +0 -124
  154. data/test/unit/class_method_test.rb +0 -200
  155. data/test/unit/date_time_inspect_test.rb +0 -21
  156. data/test/unit/expectation_error_test.rb +0 -24
  157. data/test/unit/expectation_list_test.rb +0 -75
  158. data/test/unit/expectation_raiser_test.rb +0 -28
  159. data/test/unit/expectation_test.rb +0 -483
  160. data/test/unit/hash_inspect_test.rb +0 -16
  161. data/test/unit/infinite_range_test.rb +0 -53
  162. data/test/unit/metaclass_test.rb +0 -22
  163. data/test/unit/method_matcher_test.rb +0 -23
  164. data/test/unit/missing_expectation_test.rb +0 -42
  165. data/test/unit/mock_test.rb +0 -323
  166. data/test/unit/multiple_yields_test.rb +0 -18
  167. data/test/unit/no_yield_test.rb +0 -18
  168. data/test/unit/object_inspect_test.rb +0 -37
  169. data/test/unit/object_test.rb +0 -165
  170. data/test/unit/parameter_matchers/all_of_test.rb +0 -26
  171. data/test/unit/parameter_matchers/any_of_test.rb +0 -26
  172. data/test/unit/parameter_matchers/anything_test.rb +0 -21
  173. data/test/unit/parameter_matchers/has_entries_test.rb +0 -30
  174. data/test/unit/parameter_matchers/has_entry_test.rb +0 -40
  175. data/test/unit/parameter_matchers/has_key_test.rb +0 -25
  176. data/test/unit/parameter_matchers/has_value_test.rb +0 -25
  177. data/test/unit/parameter_matchers/includes_test.rb +0 -25
  178. data/test/unit/parameter_matchers/instance_of_test.rb +0 -25
  179. data/test/unit/parameter_matchers/is_a_test.rb +0 -25
  180. data/test/unit/parameter_matchers/kind_of_test.rb +0 -25
  181. data/test/unit/parameter_matchers/not_test.rb +0 -26
  182. data/test/unit/parameter_matchers/regexp_matches_test.rb +0 -25
  183. data/test/unit/parameter_matchers/stub_matcher.rb +0 -23
  184. data/test/unit/parameters_matcher_test.rb +0 -121
  185. data/test/unit/return_values_test.rb +0 -63
  186. data/test/unit/sequence_test.rb +0 -104
  187. data/test/unit/setup_and_teardown_test.rb +0 -76
  188. data/test/unit/single_return_value_test.rb +0 -33
  189. data/test/unit/single_yield_test.rb +0 -18
  190. data/test/unit/string_inspect_test.rb +0 -11
  191. data/test/unit/stub_test.rb +0 -24
  192. data/test/unit/yield_parameters_test.rb +0 -93
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 44d35f56fc0395b34a514c91a44a914ac782a500a4426db9e7c00aea8ae66c96
4
+ data.tar.gz: 2be9168ce81c71de23b3ba15593184274098938bdad1108226231c3a70fdb172
5
+ SHA512:
6
+ metadata.gz: d2fe09345542097c73fdc4594ed43d6d737b5927dd29672b79e1d94fce9550ab580c38d0855524eb193eed9b7969078e6e2ad62f11a78156e48288d27b907c78
7
+ data.tar.gz: f17bfeb0fdc2ba83a65e69f515094c00da41b25de979b5bd75767b235fd9cc0e086673a7807d0b895474792a4760e81283b3bc0ba980e67899870f84c9dd638c
data/.gemtest ADDED
File without changes
@@ -0,0 +1 @@
1
+ github: floehopper
data/.rubocop.yml ADDED
@@ -0,0 +1,92 @@
1
+ plugins:
2
+ - rubocop-rake
3
+
4
+ inherit_from: .rubocop_todo.yml
5
+
6
+ inherit_mode:
7
+ merge:
8
+ - Include
9
+
10
+ AllCops:
11
+ TargetRubyVersion: 2.2
12
+
13
+ Include:
14
+ - "**/Gemfile.*"
15
+
16
+ Exclude:
17
+ - "**/Gemfile*.lock"
18
+
19
+ NewCops: enable
20
+
21
+ # Even the reference in the documentation suggests that you should prefer
22
+ # `alias_method` vs `alias`, so I don't understand why that isn't the default.
23
+ Style/Alias:
24
+ EnforcedStyle: prefer_alias_method
25
+
26
+ Style/Documentation:
27
+ Enabled: false
28
+
29
+ # Kernel#__dir__ has only been available since Ruby v2.0
30
+ Style/ExpandPathArguments:
31
+ Enabled: false
32
+
33
+ # I'm not keen on this cop, because it's easy to miss the conditional
34
+ # I think the results are particularly unhelpful when Metrics/LineLength is big
35
+ Style/IfUnlessModifier:
36
+ Enabled: false
37
+
38
+ # Lambda literal syntax has only been supported since Ruby v2.0
39
+ Style/Lambda:
40
+ EnforcedStyle: lambda
41
+
42
+ # Symbol array literal syntax has only been supported since Ruby v2.0
43
+ Style/SymbolArray:
44
+ Enabled: false
45
+
46
+ # I'm not keen on this cop, because it's easy to miss the while/until
47
+ Style/WhileUntilModifier:
48
+ Enabled: false
49
+
50
+ # This recently introduced cop seems to have stirred up some controversy
51
+ Style/AccessModifierDeclarations:
52
+ Enabled: false
53
+
54
+ # `Module#===` is useful in presence of objects such as mocks
55
+ # that may have a `is_a?` implementation that lies.
56
+ Style/CaseEquality:
57
+ Enabled: false
58
+
59
+ # This is useful when using `ExecutionPoint.current` to make tests more robust
60
+ Style/Semicolon:
61
+ Enabled: false
62
+
63
+ # Enabling this cop results in an "Infinite loop detected" exception
64
+ Layout/AccessModifierIndentation:
65
+ Enabled: false
66
+
67
+ # Allow long comment lines, e.g. YARD documentation
68
+ Layout/LineLength:
69
+ AllowedPatterns: ['\A\s*#']
70
+
71
+ # It's not possible to set TargetRubyVersion to Ruby < v2.2
72
+ Gemspec/RequiredRubyVersion:
73
+ Enabled: false
74
+
75
+ # This cop is useful for required environment variables, but not for optional ones
76
+ Style/FetchEnvVar:
77
+ AllowedVars:
78
+ - MOCHA_RUN_INTEGRATION_TESTS
79
+
80
+ Naming/FileName:
81
+ ExpectMatchingDefinition: true
82
+ Exclude:
83
+ - lib/mocha/version.rb
84
+ - lib/mocha/minitest.rb
85
+ - lib/mocha/test_unit.rb
86
+ - lib/mocha/ruby_version.rb
87
+ - lib/mocha/macos_version.rb
88
+ - test/test_helper.rb
89
+
90
+ Metrics/BlockLength:
91
+ Exclude:
92
+ - "Rakefile"
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,39 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2025-01-03 14:37:32 UTC using RuboCop version 1.69.2.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 34
10
+ # Configuration parameters: AllowedMethods, AllowedPatterns, CountRepeatedAttributes.
11
+ Metrics/AbcSize:
12
+ Max: 27
13
+
14
+ # Offense count: 28
15
+ # Configuration parameters: CountComments, CountAsOne.
16
+ Metrics/ClassLength:
17
+ Max: 381
18
+
19
+ # Offense count: 2
20
+ # Configuration parameters: AllowedMethods, AllowedPatterns.
21
+ Metrics/CyclomaticComplexity:
22
+ Max: 9
23
+
24
+ # Offense count: 200
25
+ # Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
26
+ Metrics/MethodLength:
27
+ Max: 27
28
+
29
+ # Offense count: 3
30
+ # Configuration parameters: AllowedMethods, AllowedPatterns.
31
+ Metrics/PerceivedComplexity:
32
+ Max: 10
33
+
34
+ # Offense count: 68
35
+ # This cop supports safe autocorrection (--autocorrect).
36
+ # Configuration parameters: AllowHeredoc, AllowURI, URISchemes, IgnoreCopDirectives, AllowedPatterns, SplitStrings.
37
+ # URISchemes: http, https
38
+ Layout/LineLength:
39
+ Max: 173
data/.yardopts ADDED
@@ -0,0 +1,25 @@
1
+ --output-dir docs
2
+ --no-private
3
+ lib/mocha.rb
4
+ lib/mocha/api.rb
5
+ lib/mocha/hooks.rb
6
+ lib/mocha/mock.rb
7
+ lib/mocha/expectation.rb
8
+ lib/mocha/object_methods.rb
9
+ lib/mocha/class_methods.rb
10
+ lib/mocha/parameter_matchers.rb
11
+ lib/mocha/parameter_matchers
12
+ lib/mocha/state_machine.rb
13
+ lib/mocha/sequence.rb
14
+ lib/mocha/configuration.rb
15
+ lib/mocha/expectation_error_factory.rb
16
+ lib/mocha/expectation_error.rb
17
+ lib/mocha/stubbing_error.rb
18
+ lib/mocha/unexpected_invocation.rb
19
+ lib/mocha/integration.rb
20
+ lib/mocha/integration/test_unit/adapter.rb
21
+ lib/mocha/integration/minitest/adapter.rb
22
+ -
23
+ RELEASE.md
24
+ COPYING.md
25
+ MIT-LICENSE.md
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,7 @@
1
+ * Pull requests are welcomed.
2
+ * Fork the repository.
3
+ * Make your changes in a branch.
4
+ * Add/modify/remove tests as appropriate.
5
+ * Open a pull request based on a branch on your fork.
6
+ * Wait for your pull request build to pass on [Circle CI](https://app.circleci.com/pipelines/github/freerange/mocha).
7
+ * Pull requests with failing tests will not be accepted.
data/COPYING.md ADDED
@@ -0,0 +1,3 @@
1
+ Copyright James Mead 2006
2
+
3
+ You may use, copy and redistribute this library under the same terms as [Ruby itself](https://www.ruby-lang.org/en/about/license.txt) or under the [MIT license](https://mit-license.org/).
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'benchmark'
7
+ gem 'introspection', '~> 0.0.1'
8
+ gem 'minitest'
9
+ gem 'rake'
10
+
11
+ if ENV['MOCHA_GENERATE_DOCS']
12
+ gem 'irb'
13
+ gem 'rdoc'
14
+ gem 'redcarpet'
15
+ gem 'yard'
16
+ end
17
+ end
@@ -1,7 +1,7 @@
1
- Copyright (c) 2006 Revieworld Ltd.
1
+ Copyright (c) 2006 James Mead
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
4
 
5
5
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
6
 
7
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,361 @@
1
+ ## Mocha [![CircleCI status of freerange/mocha](https://circleci.com/gh/freerange/mocha.svg?style=shield)](https://app.circleci.com/pipelines/github/freerange/mocha) [![Gem Version](https://badge.fury.io/rb/mocha.svg)](http://badge.fury.io/rb/mocha)
2
+
3
+ ### Description
4
+
5
+ * A Ruby library for [mocking](http://xunitpatterns.com/Mock%20Object.html) and [stubbing](http://xunitpatterns.com/Test%20Stub.html) - but deliberately not (yet) [faking](http://xunitpatterns.com/Fake%20Object.html) or [spying](http://xunitpatterns.com/Test%20Spy.html).
6
+ * A unified, simple and readable syntax for both full & partial mocking.
7
+ * Built-in support for Minitest and Test::Unit.
8
+ * Supported by many other test frameworks.
9
+
10
+ ### Intended Usage
11
+
12
+ Mocha is intended to be used in unit tests for the [Mock Object](http://xunitpatterns.com/Mock%20Object.html) or [Test Stub](http://xunitpatterns.com/Test%20Stub.html) types of [Test Double](http://xunitpatterns.com/Test%20Double.html), not the [Fake Object](http://xunitpatterns.com/Fake%20Object.html) or [Test Spy](http://xunitpatterns.com/Test%20Spy.html) types. Although it would be possible to extend Mocha to allow the implementation of fakes and spies, we have chosen to keep it focused on mocks and stubs.
13
+
14
+ ### Installation
15
+
16
+ #### Gem
17
+
18
+ Install the latest version of the gem with the following command...
19
+
20
+ $ gem install mocha
21
+
22
+ Note: If you are intending to use Mocha with Test::Unit or Minitest, you should only setup Mocha *after* loading the relevant test library...
23
+
24
+ ##### Test::Unit
25
+
26
+ ```ruby
27
+ require 'rubygems'
28
+ gem 'mocha'
29
+ require 'test/unit'
30
+ require 'mocha/test_unit'
31
+ ```
32
+
33
+ ##### Minitest
34
+
35
+ ```ruby
36
+ require 'rubygems'
37
+ gem 'mocha'
38
+ require 'minitest/autorun'
39
+ require 'mocha/minitest'
40
+ ```
41
+
42
+ #### Bundler
43
+
44
+ If you're using Bundler, include Mocha in the `Gemfile` and then setup Mocha later once you know the test library has been loaded...
45
+
46
+ ##### Test::Unit
47
+
48
+ ```ruby
49
+ # Gemfile
50
+ gem 'mocha'
51
+
52
+ # Elsewhere after Bundler has loaded gems e.g. after `require 'bundler/setup'`
53
+ require 'test/unit'
54
+ require 'mocha/test_unit'
55
+ ```
56
+
57
+ ##### Minitest
58
+
59
+ ```ruby
60
+ # Gemfile
61
+ gem 'mocha'
62
+
63
+ # Elsewhere after Bundler has loaded gems e.g. after `require 'bundler/setup'`
64
+ require 'minitest/autorun'
65
+ require 'mocha/minitest'
66
+ ```
67
+
68
+ ##### RSpec
69
+
70
+ RSpec includes a mocha adapter. Just tell RSpec you want to mock with `:mocha`:
71
+
72
+ ```ruby
73
+ # Gemfile in Rails app
74
+ gem 'mocha'
75
+
76
+ # Within `spec/spec_helper.rb`
77
+ RSpec.configure do |config|
78
+ config.mock_with :mocha
79
+ end
80
+ ```
81
+
82
+ Note: There is no need to use a require statement to setup Mocha; RSpec does this itself.
83
+
84
+ ##### Cucumber
85
+
86
+ ```ruby
87
+ # In e.g. features/support/mocha.rb
88
+ require 'mocha/api'
89
+
90
+ World(Mocha::API)
91
+
92
+ Around do |scenario, block|
93
+ begin
94
+ mocha_setup
95
+ block.call
96
+ mocha_verify
97
+ ensure
98
+ mocha_teardown
99
+ end
100
+ end
101
+ ```
102
+
103
+ #### Rails
104
+
105
+ If you're loading Mocha using Bundler within a Rails application, you should setup Mocha manually e.g. at the bottom of your `test_helper.rb`.
106
+
107
+ ##### Minitest
108
+
109
+ Note that since Rails v4 (at least), `ActiveSupport::TestCase` has inherited from `Minitest::Test` or its earlier equivalents. Thus unless you are *explicitly* using Test::Unit, you are likely to be using Minitest.
110
+
111
+ ```ruby
112
+ # Gemfile in Rails app
113
+ gem 'mocha'
114
+
115
+ # At bottom of test_helper.rb (or at least after `require 'rails/test_help'`)
116
+ require 'mocha/minitest'
117
+ ```
118
+
119
+ ##### Other Test Framework
120
+
121
+ Follow the instructions for the relevant test framework in the [Bundler](#bundler) section, but ensure that the relevant Mocha file (`mocha/minitest`, `mocha/test_unit`, or `mocha/api`) is required **after** the test framework has been loaded, e.g. at the bottom of `test_helper.rb` or `spec_helper.rb`, or at least after `rails/test_help` has been required.
122
+
123
+ #### Known Issues
124
+
125
+ * Prior to v1.15.0 (when support for Ruby v1.8 was dropped), stubbing an aliased class method where the original method is defined in a module that's used to `extend` the class doesn't work in Ruby v1.8. See `test/acceptance/stub_method_defined_on_module_and_aliased_test.rb` for an example of this behaviour.
126
+
127
+ ### Usage
128
+
129
+ #### Quick Start
130
+
131
+ ```ruby
132
+ require 'test/unit'
133
+ require 'mocha/test_unit'
134
+
135
+ class MiscExampleTest < Test::Unit::TestCase
136
+ def test_mocking_a_class_method
137
+ product = Product.new
138
+ Product.expects(:find).with(1).returns(product)
139
+ assert_equal product, Product.find(1)
140
+ end
141
+
142
+ def test_mocking_an_instance_method_on_a_real_object
143
+ product = Product.new
144
+ product.expects(:save).returns(true)
145
+ assert product.save
146
+ end
147
+
148
+ def test_stubbing_instance_methods_on_real_objects
149
+ prices = [stub(pence: 1000), stub(pence: 2000)]
150
+ product = Product.new
151
+ product.stubs(:prices).returns(prices)
152
+ assert_equal [1000, 2000], product.prices.collect {|p| p.pence}
153
+ end
154
+
155
+ def test_stubbing_an_instance_method_on_all_instances_of_a_class
156
+ Product.any_instance.stubs(:name).returns('stubbed_name')
157
+ product = Product.new
158
+ assert_equal 'stubbed_name', product.name
159
+ end
160
+
161
+ def test_traditional_mocking
162
+ object = mock('object')
163
+ object.expects(:expected_method).with(:p1, :p2).returns(:result)
164
+ assert_equal :result, object.expected_method(:p1, :p2)
165
+ end
166
+
167
+ def test_shortcuts
168
+ object = stub(method1: :result1, method2: :result2)
169
+ assert_equal :result1, object.method1
170
+ assert_equal :result2, object.method2
171
+ end
172
+ end
173
+ ```
174
+
175
+ #### Mock Objects
176
+
177
+ ```ruby
178
+ class Enterprise
179
+ def initialize(dilithium)
180
+ @dilithium = dilithium
181
+ end
182
+
183
+ def go(warp_factor)
184
+ warp_factor.times { @dilithium.nuke(:anti_matter) }
185
+ end
186
+ end
187
+
188
+ require 'test/unit'
189
+ require 'mocha/test_unit'
190
+
191
+ class EnterpriseTest < Test::Unit::TestCase
192
+ def test_should_boldly_go
193
+ dilithium = mock()
194
+ dilithium.expects(:nuke).with(:anti_matter).at_least_once # auto-verified at end of test
195
+ enterprise = Enterprise.new(dilithium)
196
+ enterprise.go(2)
197
+ end
198
+ end
199
+ ```
200
+
201
+ #### Partial Mocking
202
+
203
+ ```ruby
204
+ class Order
205
+ attr_accessor :shipped_on
206
+
207
+ def total_cost
208
+ line_items.inject(0) { |total, line_item| total + line_item.price } + shipping_cost
209
+ end
210
+
211
+ def total_weight
212
+ line_items.inject(0) { |total, line_item| total + line_item.weight }
213
+ end
214
+
215
+ def shipping_cost
216
+ total_weight * 5 + 10
217
+ end
218
+
219
+ class << self
220
+ def find_all
221
+ # Database.connection.execute('select * from orders...
222
+ end
223
+
224
+ def number_shipped_since(date)
225
+ find_all.select { |order| order.shipped_on > date }.length
226
+ end
227
+
228
+ def unshipped_value
229
+ find_all.inject(0) { |total, order| order.shipped_on ? total : total + order.total_cost }
230
+ end
231
+ end
232
+ end
233
+
234
+ require 'test/unit'
235
+ require 'mocha/test_unit'
236
+
237
+ class OrderTest < Test::Unit::TestCase
238
+ # illustrates stubbing instance method
239
+ def test_should_calculate_shipping_cost_based_on_total_weight
240
+ order = Order.new
241
+ order.stubs(:total_weight).returns(10)
242
+ assert_equal 60, order.shipping_cost
243
+ end
244
+
245
+ # illustrates stubbing class method
246
+ def test_should_count_number_of_orders_shipped_after_specified_date
247
+ now = Time.now; week_in_secs = 7 * 24 * 60 * 60
248
+ order_1 = Order.new; order_1.shipped_on = now - 1 * week_in_secs
249
+ order_2 = Order.new; order_2.shipped_on = now - 3 * week_in_secs
250
+ Order.stubs(:find_all).returns([order_1, order_2])
251
+ assert_equal 1, Order.number_shipped_since(now - 2 * week_in_secs)
252
+ end
253
+
254
+ # illustrates stubbing instance method for all instances of a class
255
+ def test_should_calculate_value_of_unshipped_orders
256
+ Order.stubs(:find_all).returns([Order.new, Order.new, Order.new])
257
+ Order.any_instance.stubs(:shipped_on).returns(nil)
258
+ Order.any_instance.stubs(:total_cost).returns(10)
259
+ assert_equal 30, Order.unshipped_value
260
+ end
261
+ end
262
+ ```
263
+
264
+ ### Thread safety
265
+
266
+ Mocha currently *does not* attempt to be thread-safe.
267
+
268
+ #### Can I test multi-threaded code with Mocha?
269
+
270
+ The short answer is no. In multi-threaded code Mocha exceptions may be raised in a thread other than the one which is running the test and thus a Mocha exception may not be correctly intercepted by Mocha exception handling code.
271
+
272
+ #### Can I run my tests across multiple threads?
273
+
274
+ Maybe, but probably not. Partial mocking changes the state of objects in the `ObjectSpace` which is shared across all threads in the Ruby process and this access to what is effectively global state is not synchronized. So, for example, if two tests are running concurrently and one uses `#any_instance` to modify a class, both tests will see those changes immediately.
275
+
276
+ ### Expectation matching / invocation order
277
+
278
+ Stubs and expectations are basically the same thing. A stub is just an expectation of zero or more invocations. The `Expectation#stubs` method is syntactic sugar to make the intent of the test more explicit.
279
+
280
+ When a method is invoked on a mock object, the mock object searches through its expectations from newest to oldest to find one that matches the invocation. After the invocation, the matching expectation might stop matching further invocations. If the expectation that matches the invocation has a cardinality of "never", then an unexpected invocation error is reported.
281
+
282
+ See the [documentation](https://mocha.jamesmead.org/Mocha/Mock.html) for `Mocha::Mock` for further details.
283
+
284
+ ### Configuration
285
+
286
+ If you want, Mocha can generate a warning or raise an exception when:
287
+
288
+ * stubbing a method unnecessarily
289
+ * stubbing method on a non-mock object
290
+ * stubbing a non-existent method
291
+ * stubbing a non-public method
292
+
293
+ See the [documentation](https://mocha.jamesmead.org/Mocha/Configuration.html) for `Mocha::Configuration` for further details.
294
+
295
+ ### Debugging
296
+
297
+ Mocha provides some extra output to help with debugging when the standard Ruby debug option (`-d`) is set.
298
+
299
+ ### Semantic versioning
300
+
301
+ * Every effort is made to comply with [semantic versioning](https://semver.org/).
302
+ * However, this only applies to the behaviour documented in the public API.
303
+ * The documented public API does *not* include the content or format of messsages displayed to the user, e.g. assertion failure messages.
304
+
305
+ ### Useful Links
306
+
307
+ * [Official Documentation](https://mocha.jamesmead.org)
308
+ * [Source Code](http://github.com/freerange/mocha)
309
+ * [Mailing List](http://groups.google.com/group/mocha-developer)
310
+ * [James Mead's Blog](http://jamesmead.org/blog/)
311
+ * [An Introduction To Mock Objects In Ruby](http://jamesmead.org/talks/2007-07-09-introduction-to-mock-objects-in-ruby-at-lrug/)
312
+ * [Mocks Aren't Stubs](http://martinfowler.com/articles/mocksArentStubs.html)
313
+ * [Growing Object-Oriented Software Guided By Tests](http://www.growing-object-oriented-software.com/)
314
+ * [Mock Roles Not Objects](http://www.jmock.org/oopsla2004.pdf)
315
+ * [jMock](http://www.jmock.org/)
316
+
317
+ ### Contributors
318
+
319
+ See this [list of contributors](https://github.com/freerange/mocha/graphs/contributors).
320
+
321
+ ### Releasing a new version
322
+
323
+ * Update the RELEASE.md file with a summary of changes
324
+ * Bump the version in `lib/mocha/version.rb`
325
+ * Commit & push to GitHub
326
+ * Check CircleCI build is passing - https://app.circleci.com/pipelines/github/freerange/mocha
327
+
328
+ * Generate documentation:
329
+
330
+ ```bash
331
+ $ MOCHA_GENERATE_DOCS=true bundle install
332
+
333
+ $ MOCHA_GENERATE_DOCS=true bundle exec rake docs
334
+ ```
335
+ * Commit documentation & push to GitHub
336
+ * Sign in to rubygems.org and find API key - https://rubygems.org/profile/edit
337
+
338
+ ```bash
339
+ $ curl -u <email-address> -H 'OTP:<one-time-password>' https://rubygems.org/api/v1/api_key.yaml > ~/.gem/credentials; chmod 0600 ~/.gem/credentials
340
+ ```
341
+
342
+ * Release gem to Rubygems:
343
+
344
+ ```bash
345
+ $ bundle exec rake release
346
+ [runs tests]
347
+ mocha 1.2.0 built to pkg/mocha-1.2.0.gem.
348
+ Tagged v1.2.0.
349
+ Pushed git commits and tags.
350
+ Pushed mocha 1.2.0 to rubygems.org.
351
+ ```
352
+
353
+ ### History
354
+
355
+ Mocha was initially harvested from projects at [Reevoo](http://www.reevoo.com/). It's syntax is heavily based on that of [jMock](http://www.jmock.org).
356
+
357
+ ### License
358
+
359
+ &copy; Copyright James Mead 2006
360
+
361
+ You may use, copy and redistribute this library under the same terms as [Ruby itself](https://www.ruby-lang.org/en/about/license.txt) or under the [MIT license](https://mit-license.org/).