PageRenderTime 47ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/third-party/gem/gems/flexmock-0.8.6/test/test_partial_mock.rb

https://github.com/mulderp/growing-oo-software-in-ruby
Ruby | 361 lines | 292 code | 55 blank | 14 comment | 3 complexity | 2e8dea1a26acd37c94b453e9744a03a3 MD5 | raw file
  1. #!/usr/bin/env ruby
  2. #---
  3. # Copyright 2003, 2004, 2005, 2006, 2007 by Jim Weirich (jim@weirichhouse.org).
  4. # All rights reserved.
  5. # Permission is granted for use, copying, modification, distribution,
  6. # and distribution of modified versions of this work as long as the
  7. # above copyright notice is included.
  8. #+++
  9. require 'test/unit'
  10. require 'fileutils'
  11. require 'flexmock'
  12. class TestStubbing < Test::Unit::TestCase
  13. include FlexMock::TestCase
  14. class Dog
  15. def bark
  16. :woof
  17. end
  18. def Dog.create
  19. :new_dog
  20. end
  21. end
  22. class DogPlus < Dog
  23. def should_receive
  24. :dog_should
  25. end
  26. def new_instances
  27. :dog_new
  28. end
  29. def by_default
  30. :dog_by_default
  31. end
  32. end
  33. def test_stub_command_add_behavior_to_arbitrary_objects
  34. obj = Object.new
  35. flexmock(obj).should_receive(:hi).once.and_return(:stub_hi)
  36. assert_equal :stub_hi, obj.hi
  37. end
  38. def test_stub_command_can_configure_via_block
  39. obj = Object.new
  40. flexmock(obj) do |m|
  41. m.should_receive(:hi).once.and_return(:stub_hi)
  42. end
  43. assert_equal :stub_hi, obj.hi
  44. end
  45. def test_stubbed_methods_can_take_blocks
  46. obj = Object.new
  47. flexmock(obj).should_receive(:with_block).once.with(Proc).
  48. and_return { |block| block.call }
  49. assert_equal :block, obj.with_block { :block }
  50. end
  51. def test_multiple_stubs_on_the_same_object_reuse_the_same_partial_mock
  52. obj = Object.new
  53. assert_equal flexmock(obj), flexmock(obj)
  54. end
  55. def test_multiple_methods_can_be_stubbed
  56. dog = Dog.new
  57. flexmock(dog).should_receive(:bark).and_return(:grrrr)
  58. flexmock(dog).should_receive(:wag).and_return(:happy)
  59. assert_equal :grrrr, dog.bark
  60. assert_equal :happy, dog.wag
  61. end
  62. def test_original_behavior_can_be_restored
  63. dog = Dog.new
  64. partial_mock = flexmock(dog)
  65. partial_mock.should_receive(:bark).once.and_return(:growl)
  66. assert_equal :growl, dog.bark
  67. partial_mock.flexmock_teardown
  68. assert_equal :woof, dog.bark
  69. assert_equal nil, dog.instance_variable_get("@flexmock_proxy")
  70. end
  71. def test_original_missing_behavior_can_be_restored
  72. obj = Object.new
  73. partial_mock = flexmock(obj)
  74. partial_mock.should_receive(:hi).once.and_return(:ok)
  75. assert_equal :ok, obj.hi
  76. partial_mock.flexmock_teardown
  77. assert_raise(NoMethodError) { obj.hi }
  78. end
  79. def test_multiple_stubs_on_single_method_can_be_restored_missing_method
  80. obj = Object.new
  81. partial_mock = flexmock(obj)
  82. partial_mock.should_receive(:hi).with(1).once.and_return(:ok)
  83. partial_mock.should_receive(:hi).with(2).once.and_return(:ok)
  84. assert_equal :ok, obj.hi(1)
  85. assert_equal :ok, obj.hi(2)
  86. partial_mock.flexmock_teardown
  87. assert_raise(NoMethodError) { obj.hi }
  88. end
  89. def test_original_behavior_is_restored_when_multiple_methods_are_mocked
  90. dog = Dog.new
  91. flexmock(dog).should_receive(:bark).and_return(:grrrr)
  92. flexmock(dog).should_receive(:wag).and_return(:happy)
  93. flexmock(dog).flexmock_teardown
  94. assert_equal :woof, dog.bark
  95. assert_raise(NoMethodError) { dog.wag }
  96. end
  97. def test_original_behavior_is_restored_on_class_objects
  98. flexmock(Dog).should_receive(:create).once.and_return(:new_stub)
  99. assert_equal :new_stub, Dog.create
  100. flexmock(Dog).flexmock_teardown
  101. assert_equal :new_dog, Dog.create
  102. end
  103. def test_original_behavior_is_restored_on_singleton_methods
  104. obj = Object.new
  105. def obj.hi() :hello end
  106. flexmock(obj).should_receive(:hi).once.and_return(:hola)
  107. assert_equal :hola, obj.hi
  108. flexmock(obj).flexmock_teardown
  109. assert_equal :hello, obj.hi
  110. end
  111. def test_original_behavior_is_restored_on_singleton_methods_with_multiple_stubs
  112. obj = Object.new
  113. def obj.hi(n) "hello#{n}" end
  114. flexmock(obj).should_receive(:hi).with(1).once.and_return(:hola)
  115. flexmock(obj).should_receive(:hi).with(2).once.and_return(:hola)
  116. assert_equal :hola, obj.hi(1)
  117. assert_equal :hola, obj.hi(2)
  118. flexmock(obj).flexmock_teardown
  119. assert_equal "hello3", obj.hi(3)
  120. end
  121. def test_original_behavior_is_restored_on_nonsingleton_methods_with_multiple_stubs
  122. flexmock(Dir).should_receive(:chdir).with("xx").once.and_return(:ok1)
  123. flexmock(Dir).should_receive(:chdir).with("yy").once.and_return(:ok2)
  124. assert_equal :ok1, Dir.chdir("xx")
  125. assert_equal :ok2, Dir.chdir("yy")
  126. flexmock(Dir).flexmock_teardown
  127. x = :not_called
  128. Dir.chdir("test") do
  129. assert_match %r{/test$}, Dir.pwd
  130. x = :called
  131. end
  132. assert_equal :called, x
  133. end
  134. def test_stubbing_file_shouldnt_break_writing
  135. flexmock(File).should_receive(:open).with("foo").once.and_return(:ok)
  136. assert_equal :ok, File.open("foo")
  137. flexmock(File).flexmock_teardown
  138. File.open("dummy.txt", "w") do |out|
  139. assert out.is_a?(IO)
  140. out.puts "XYZ"
  141. end
  142. text = nil
  143. File.open("dummy.txt") { |f| text = f.read }
  144. assert_equal "XYZ\n", text
  145. ensure
  146. FileUtils.rm_f("dummy.txt")
  147. end
  148. def test_original_behavior_is_restored_even_when_errors
  149. flexmock(Dog).should_receive(:create).once.and_return(:mock)
  150. flexmock_teardown rescue nil
  151. assert_equal :new_dog, Dog.create
  152. # Now disable the mock so that it doesn't cause errors on normal
  153. # test teardown
  154. m = flexmock(Dog).flexmock_get
  155. def m.flexmock_verify() end
  156. end
  157. def test_not_calling_stubbed_method_is_an_error
  158. dog = Dog.new
  159. flexmock(dog).should_receive(:bark).once
  160. assert_raise(Test::Unit::AssertionFailedError) {
  161. flexmock(dog).flexmock_verify
  162. }
  163. dog.bark
  164. end
  165. def test_mock_is_verified_when_the_stub_is_verified
  166. obj = Object.new
  167. partial_mock = flexmock(obj)
  168. partial_mock.should_receive(:hi).once.and_return(:ok)
  169. assert_raise(Test::Unit::AssertionFailedError) {
  170. partial_mock.flexmock_verify
  171. }
  172. end
  173. def test_stub_can_have_explicit_name
  174. obj = Object.new
  175. partial_mock = flexmock(obj, "Charlie")
  176. assert_equal "Charlie", partial_mock.flexmock_get.flexmock_name
  177. end
  178. def test_unamed_stub_will_use_default_naming_convention
  179. obj = Object.new
  180. partial_mock = flexmock(obj)
  181. assert_equal "flexmock(Object)", partial_mock.flexmock_get.flexmock_name
  182. end
  183. def test_partials_can_be_defined_in_a_block
  184. dog = Dog.new
  185. flexmock(dog) do |m|
  186. m.should_receive(:bark).and_return(:growl)
  187. end
  188. assert_equal :growl, dog.bark
  189. end
  190. def test_partials_defining_block_return_real_obj_not_proxy
  191. dog = flexmock(Dog.new) do |m|
  192. m.should_receive(:bark).and_return(:growl)
  193. end
  194. assert_equal :growl, dog.bark
  195. end
  196. def test_partial_mocks_always_return_domain_object
  197. dog = Dog.new
  198. assert_equal dog, flexmock(dog)
  199. assert_equal dog, flexmock(dog) { }
  200. end
  201. MOCK_METHOD_SUBSET = [
  202. :should_receive, :new_instances,
  203. :flexmock_get, :flexmock_teardown, :flexmock_verify,
  204. ]
  205. def test_domain_objects_do_not_have_mock_methods
  206. dog = Dog.new
  207. MOCK_METHOD_SUBSET.each do |sym|
  208. assert ! dog.respond_to?(sym), "should not have :#{sym} defined"
  209. end
  210. end
  211. def test_partial_mocks_have_mock_methods
  212. dog = Dog.new
  213. flexmock(dog)
  214. MOCK_METHOD_SUBSET.each do |sym|
  215. assert dog.respond_to?(sym), "should have :#{sym} defined"
  216. end
  217. end
  218. def test_partial_mocks_do_not_have_mock_methods_after_teardown
  219. dog = Dog.new
  220. flexmock(dog)
  221. dog.flexmock_teardown
  222. MOCK_METHOD_SUBSET.each do |sym|
  223. assert ! dog.respond_to?(sym), "should not have :#{sym} defined"
  224. end
  225. end
  226. def test_partial_mocks_with_mock_method_singleton_colision_have_original_defs_restored
  227. dog = Dog.new
  228. def dog.mock() :original end
  229. flexmock(dog)
  230. dog.flexmock_teardown
  231. assert_equal :original, dog.mock
  232. end
  233. class MockColision
  234. def mock
  235. :original
  236. end
  237. end
  238. def test_partial_mocks_with_mock_method_non_singleton_colision_have_original_defs_restored
  239. mc = MockColision.new
  240. flexmock(mc)
  241. mc.flexmock_teardown
  242. assert_equal :original, mc.mock
  243. end
  244. def test_safe_partial_mocks_do_not_support_mock_methods
  245. dog = Dog.new
  246. flexmock(:safe, dog) { }
  247. MOCK_METHOD_SUBSET.each do |sym|
  248. assert ! dog.respond_to?(sym), "should not have :#{sym} defined"
  249. end
  250. end
  251. def test_safe_partial_mocks_require_block
  252. dog = Dog.new
  253. ex = assert_raise(FlexMock::UsageError) { flexmock(:safe, dog) }
  254. end
  255. def test_safe_partial_mocks_are_actually_mocked
  256. dog = flexmock(:safe, Dog.new) { |m| m.should_receive(:bark => :mocked) }
  257. assert_equal :mocked, dog.bark
  258. end
  259. def test_should_receive_does_not_override_preexisting_def
  260. dog = flexmock(DogPlus.new)
  261. assert_equal :dog_new, dog.new_instances
  262. assert_equal :dog_by_default, dog.by_default
  263. end
  264. def test_should_receive_does_override_should_receive_preexisting_def
  265. dog = flexmock(DogPlus.new)
  266. assert_kind_of FlexMock::CompositeExpectation, dog.should_receive(:x)
  267. end
  268. class Liar
  269. def respond_to?(method_name)
  270. sym = method_name.to_sym
  271. if sym == :not_defined
  272. true
  273. else
  274. super(method_name)
  275. end
  276. end
  277. end
  278. def test_liar_actually_lies
  279. liar = Liar.new
  280. assert liar.respond_to?(:not_defined)
  281. assert_raise(NoMethodError) { liar.not_defined }
  282. end
  283. def test_partial_mock_where_respond_to_is_true_yet_method_is_not_there
  284. liar = Liar.new
  285. flexmock(liar, :not_defined => :xyzzy)
  286. assert_equal :xyzzy, liar.not_defined
  287. end
  288. # The following test was suggested by Pat Maddox for the RSpec
  289. # mocks. Evidently the (poorly implemented) == method caused issues
  290. # with RSpec Mock's internals. I'm just double checking for any
  291. # similar issues in FlexMock as well.
  292. class ValueObject
  293. attr_reader :val
  294. def initialize(val)
  295. @val = val
  296. end
  297. def ==(other)
  298. @val == other.val
  299. end
  300. end
  301. def test_partial_mocks_in_the_presense_of_equal_definition
  302. flexmock("existing obj", :foo => :foo)
  303. obj = ValueObject.new(:bar)
  304. flexmock(obj, :some_method => :some_method)
  305. end
  306. end