Skip to content

Commit

Permalink
+ Added Object#stub (in minitest/mock.rb).
Browse files Browse the repository at this point in the history
[git-p4: depot-paths = "//src/minitest/dev/": change = 7432]
  • Loading branch information
zenspider committed May 9, 2012
1 parent 7ef920c commit 37e1a04
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 3 deletions.
1 change: 1 addition & 0 deletions .autotest
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Autotest.add_hook :initialize do |at|
at.extra_class_map["TestMeta"] = "test/test_minitest_spec.rb"
at.extra_class_map["TestMiniTestUnitTestCase"] = "test/test_minitest_unit.rb"
at.extra_class_map["TestMiniTestUnit"] = "test/test_minitest_unit.rb"
at.extra_class_map["TestMiniTestStub"] = "test/test_minitest_mock.rb"
at.add_exception 'coverage.info'
at.add_exception 'coverage'
end
Expand Down
18 changes: 15 additions & 3 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ algorithms in a repeatable manner. Now you can assert that your newb
co-worker doesn't replace your linear algorithm with an exponential
one!

minitest/mock by Steven Baker, is a beautifully tiny mock object
framework.
minitest/mock by Steven Baker, is a beautifully tiny mock (and stub)
object framework.

minitest/pride shows pride in testing and adds coloring to your test
output. I guess it is an example of how to write IO pipes too. :P
Expand All @@ -54,7 +54,7 @@ discovery.
* minitest/autorun - the easy and explicit way to run all your tests.
* minitest/unit - a very fast, simple, and clean test system.
* minitest/spec - a very fast, simple, and clean spec system.
* minitest/mock - a simple and clean mock system.
* minitest/mock - a simple and clean mock/stub system.
* minitest/benchmark - an awesome way to assert your algorithm's performance.
* minitest/pride - show your pride in testing!
* Incredibly small and fast runner, but no bells and whistles.
Expand Down Expand Up @@ -194,6 +194,18 @@ Output is tab-delimited to make it easy to paste into a spreadsheet.
end
end

=== Stubs

def test_stale_eh
obj_under_test = Something.new

refute obj_under_test.stale?

Time.stub :now, Time.at(0) do # stub goes away once the block is done
assert obj_under_test.stale?
end
end

=== Customizable Test Runner Types:

MiniTest::Unit.runner=(runner) provides an easy way of creating custom
Expand Down
38 changes: 38 additions & 0 deletions lib/minitest/mock.rb
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,41 @@ def respond_to?(sym) # :nodoc:
end
end
end

class Object # :nodoc:

##
# Add a temporary stubbed method replacing +name+ for the duration
# of the +block+. If +val_or_callable+ responds to #call, then it
# returns the result of calling it, otherwise returns the value
# as-is. Cleans up the stub at the end of the +block+.
#
# def test_stale_eh
# obj_under_test = Something.new
# refute obj_under_test.stale?
#
# Time.stub :now, Time.at(0) do
# assert obj_under_test.stale?
# end
# end

def stub name, val_or_callable, &block
new_name = "__minitest_stub__#{name}"

metaclass = class << self; self; end
metaclass.send :alias_method, new_name, name
metaclass.send :define_method, name do |*args|
if val_or_callable.respond_to? :call then
val_or_callable.call(*args)
else
val_or_callable
end
end

yield
ensure
metaclass.send :undef_method, name
metaclass.send :alias_method, name, new_name
metaclass.send :undef_method, new_name
end
end
59 changes: 59 additions & 0 deletions test/minitest/test_minitest_mock.rb
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,62 @@ def util_verify_bad exp
assert_equal exp, e.message
end
end

require "test/minitest/metametameta"

class TestMiniTestStub < MiniTest::Unit::TestCase
def setup
super
MiniTest::Unit::TestCase.reset

@tc = MiniTest::Unit::TestCase.new 'fake tc'
@assertion_count = 1
end

def teardown
super
assert_equal @assertion_count, @tc._assertions
end

def assert_stub val_or_callable
@assertion_count += 1

t = Time.now.to_i

Time.stub :now, val_or_callable do
@tc.assert_equal 42, Time.now
end

@tc.assert_operator Time.now.to_i, :>=, t
end

def test_stub_value
assert_stub 42
end

def test_stub_block
assert_stub lambda { 42 }
end

def test_stub_block_args
@assertion_count += 1

t = Time.now.to_i

Time.stub :now, lambda { |n| n * 2 } do
@tc.assert_equal 42, Time.now(21)
end

@tc.assert_operator Time.now.to_i, :>=, t
end

def test_stub_callable
obj = Object.new

def obj.call
42
end

assert_stub obj
end
end

2 comments on commit 37e1a04

@mongrelion
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome. Thank you very much for this.

@guilleiguaran
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this ❤️

Please sign in to comment.