Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shared tests for potential violations (stubbing non-existent/public methods, etc.) #460

Open
wants to merge 63 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
d538675
Refactor: extract method stub_method_unnecessarily
nitishr Jan 9, 2020
356d967
Refactor: extract violation message into method
nitishr Jan 9, 2020
2b58fe2
configure check only if treatment isn't default
nitishr Jan 9, 2020
7737927
Refactor: extract method run_test_with_check
nitishr Jan 9, 2020
68d6abb
Refactor: inline temps
nitishr Jan 9, 2020
964262c
define test class rather than body conditionally
nitishr Jan 9, 2020
d1665a3
extract stub_method_on_nil & violation_message
nitishr Jan 9, 2020
3ec6ac9
Refactor: inline temp
nitishr Jan 9, 2020
73f20ec
Refactor: extract method run_test_with_check
nitishr Jan 10, 2020
8c40baf
Refactor:rename method_x->with_potential_violation
nitishr Jan 10, 2020
7c0c807
Refactor: extract block to potential_violation
nitishr Jan 10, 2020
34f90ae
Refactor: extract block to configure_violation
nitishr Jan 10, 2020
c744731
Refactor: make test method name truthful
nitishr Jan 10, 2020
be0831a
extract StubbingWithPotentialViolationSharedTests
nitishr Jan 10, 2020
d136000
Refactor: reorder methods for expressiveness
nitishr Jan 10, 2020
cfb2d60
Refactor: rename for expressiveness & consistency
nitishr Jan 10, 2020
9071d2a
use shared tests in StubbingNonExistentAnyInstanceMethodTest
nitishr Jan 10, 2020
88e50e4
Refactor: extract common assertion into shared mod
nitishr Jan 10, 2020
451ec0b
use shared tests in StubbingNonExistentClassMethodTest
nitishr Jan 10, 2020
f16f1b3
use shared tests in StubbingNonExistentInstanceMethodTest
nitishr Jan 10, 2020
ad2cd32
use shared tests in StubbingOnNonMockObjectTest
nitishr Jan 10, 2020
d67f0b5
extract default to allow test to a module
nitishr Jan 10, 2020
420aec3
Refactor: rename existing*method->existing_method
nitishr Jan 10, 2020
e53c6a8
set visibility programmatically than declaratively
nitishr Jan 10, 2020
8f403ec
put mocha configure and run_as_test together
nitishr Jan 10, 2020
23f11a5
extract assert_allows_stubbing_existing_any_instance_method
nitishr Jan 10, 2020
9f6164e
Refactor: extract method class_with_method
nitishr Jan 10, 2020
307aa5a
Refactor: inline temps
nitishr Jan 10, 2020
bbcdb07
separate tests for allow stubbing existing methods
nitishr Jan 10, 2020
6f95b2f
Refactor:extract stubbee_with_method to lower diff
nitishr Jan 10, 2020
e56097a
rename tests to reduce diff between {,super}class
nitishr Jan 10, 2020
6f9b6e7
extract common {,super}class tests into a module
nitishr Jan 10, 2020
c58b383
define method programmatically than declaratively
nitishr Jan 10, 2020
0aef1b8
Refactor: push stubbee creation down a method
nitishr Jan 10, 2020
be34bf6
allow test classes to specify method_owner,stubbee
nitishr Jan 10, 2020
55cc6b9
extract stub_owner to override for class methods
nitishr Jan 14, 2020
478733c
remove any_instance qualifier to allow use for class methods
nitishr Jan 14, 2020
702992f
move mod to own file for use in class method tests
nitishr Jan 14, 2020
84f2a61
use existing method shared tests for class methods
nitishr Jan 14, 2020
bac7571
instance method tests use ExistingMethodSharedTest
nitishr Jan 14, 2020
1ae84b8
pull up test_should_allow_stubbing_method_responded_to
nitishr Jan 14, 2020
2df5eed
move mocha configure call to allow extraction
nitishr Jan 14, 2020
dae2123
Refactor: extract assert_allows_stubbing_method
nitishr Jan 14, 2020
79558ac
rename shared test mod to move related files closer
nitishr Jan 14, 2020
f9c1a65
use shared tests for non-public any_instance
nitishr Jan 14, 2020
03e25ed
reduce diff in tests for private and protected
nitishr Jan 14, 2020
1965488
Refactor: extract module w/ overridden visibility
nitishr Jan 14, 2020
c3cb560
Refactor: extract {stub,method}_owner for override
nitishr Jan 14, 2020
cf22b80
extract StubbingNonPublicMethodSharedTests
nitishr Jan 14, 2020
8f424f1
use shared mod in StubbingNonPublicClassMethodTest
nitishr Jan 14, 2020
39702b9
use shared mod in StubbingNonPublicInstanceMethodTest
nitishr Jan 14, 2020
18356c2
extract test allow stubbing public method to mod
nitishr Jan 15, 2020
af2f216
Refactor: minor rename and reorder for consistency
nitishr Jan 15, 2020
6d33106
Refactor: extract StubbingAnyInstanceMethodHelper
nitishr Jan 15, 2020
6e28fd6
Refactor: extract StubbingClassMethodHelper module
nitishr Jan 15, 2020
fe601c2
Refactor: extract StubbingInstanceMethodHelper module
nitishr Jan 15, 2020
04c4a5b
Refactor: remove modules to reduce indirection
nitishr Jan 15, 2020
b557ff8
use StubbingXMethodHelper in StubbingNonExistentXMethodTest
nitishr Jan 15, 2020
807758e
extract StubbingNonExistentMethodSharedTests
nitishr Jan 15, 2020
9d90336
Refactor: rename modules to make including tests more expressive
nitishr Jan 15, 2020
d2932ce
Refactor: extract configure_violation to reduce diff
nitishr Jan 15, 2020
8f6a9b4
use StubbingPublicMethodIsAllowed in StubbingExistingMethodIsAllowed
nitishr Jan 15, 2020
7554c38
stubbed_instance -> callee, stub_owner -> stubbee
nitishr Jan 17, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions test/acceptance/stubbing_any_instance_method.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module StubbingAnyInstanceMethod
def method_owner
@method_owner ||= Class.new
end

def stubbee
method_owner.any_instance
end
end
9 changes: 9 additions & 0 deletions test/acceptance/stubbing_class_method.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module StubbingClassMethod
def method_owner
stubbee.singleton_class
end

def stubbee
@stubbee ||= Class.new
end
end
23 changes: 23 additions & 0 deletions test/acceptance/stubbing_existing_method_is_allowed.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
require File.expand_path('../stubbing_public_method_is_allowed', __FILE__)

module StubbingExistingMethodIsAllowed
include StubbingPublicMethodIsAllowed

def test_should_allow_stubbing_existing_protected_method
assert_allows_stubbing_existing_method(:protected)
end

def test_should_allow_stubbing_existing_private_method
assert_allows_stubbing_existing_method(:private)
end

def assert_allows_stubbing_existing_method(visibility)
method_owner.send(:define_method, :existing_method) {}
method_owner.send(visibility, :existing_method)
assert_allows_stubbing_method(:existing_method)
end

def configure_violation(config, treatment)
config.stubbing_non_existent_method = treatment
end
end
9 changes: 9 additions & 0 deletions test/acceptance/stubbing_instance_method.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module StubbingInstanceMethod
def method_owner
stubbee.class
end

def stubbee
@stubbee ||= Class.new.new
end
end
56 changes: 10 additions & 46 deletions test/acceptance/stubbing_method_unnecessarily_test.rb
Original file line number Diff line number Diff line change
@@ -1,59 +1,23 @@
require File.expand_path('../acceptance_test_helper', __FILE__)
require 'mocha/configuration'
require File.expand_path('../stubbing_with_potential_violation_is_checked', __FILE__)

class StubbingMethodUnnecessarilyTest < Mocha::TestCase
include AcceptanceTest
include StubbingWithPotentialViolationIsCheckedAndAllowedByDefault

def setup
setup_acceptance_test
def configure_violation(config, treatment)
config.stubbing_method_unnecessarily = treatment
end

def teardown
teardown_acceptance_test
def potential_violation
mock = mock('mock')
mock.stubs(:public_method)
end

def test_should_allow_stubbing_method_unnecessarily
Mocha.configure { |c| c.stubbing_method_unnecessarily = :allow }
test_result = run_as_test do
mock = mock('mock')
mock.stubs(:public_method)
end
assert_passed(test_result)
assert !@logger.warnings.include?('stubbing method unnecessarily: #<Mock:mock>.public_method(any_parameters)')
end

def test_should_warn_when_stubbing_method_unnecessarily
Mocha.configure { |c| c.stubbing_method_unnecessarily = :warn }
test_result = run_as_test do
mock = mock('mock')
mock.stubs(:public_method)
end
assert_passed(test_result)
assert @logger.warnings.include?('stubbing method unnecessarily: #<Mock:mock>.public_method(any_parameters)')
end

def test_should_prevent_stubbing_method_unnecessarily
Mocha.configure { |c| c.stubbing_method_unnecessarily = :prevent }
test_result = run_as_test do
mock = mock('mock')
mock.stubs(:public_method)
end
assert_failed(test_result)
assert test_result.error_messages.include?('Mocha::StubbingError: stubbing method unnecessarily: #<Mock:mock>.public_method(any_parameters)')
end

def test_should_default_to_allow_stubbing_method_unnecessarily
test_result = run_as_test do
mock = mock('mock')
mock.stubs(:public_method)
end
assert_passed(test_result)
assert !@logger.warnings.include?('stubbing method unnecessarily: #<Mock:mock>.public_method(any_parameters)')
def message_on_violation
'stubbing method unnecessarily: #<Mock:mock>.public_method(any_parameters)'
end

def test_should_allow_stubbing_method_when_stubbed_method_is_invoked
Mocha.configure { |c| c.stubbing_method_unnecessarily = :prevent }
test_result = run_as_test do
test_result = run_test_with_check(:prevent) do
mock = mock('mock')
mock.stubs(:public_method)
mock.public_method
Expand Down
58 changes: 15 additions & 43 deletions test/acceptance/stubbing_nil_test.rb
Original file line number Diff line number Diff line change
@@ -1,58 +1,30 @@
require File.expand_path('../acceptance_test_helper', __FILE__)
require 'mocha/configuration'
require File.expand_path('../stubbing_with_potential_violation_is_checked', __FILE__)

class StubbingNilTest < Mocha::TestCase
include AcceptanceTest
if RUBY_VERSION < '2.2.0'
class StubbingNilTest < Mocha::TestCase
include StubbingWithPotentialViolationIsChecked

def setup
setup_acceptance_test
end

def teardown
teardown_acceptance_test
end

if RUBY_VERSION < '2.2.0'
def test_should_allow_stubbing_method_on_nil
Mocha.configure { |c| c.stubbing_method_on_nil = :allow }
test_result = run_as_test do
nil.stubs(:stubbed_method)
end
assert_passed(test_result)
assert !@logger.warnings.include?('stubbing method on nil: nil.stubbed_method')
def configure_violation(config, treatment)
config.stubbing_method_on_nil = treatment
end

def test_should_warn_on_stubbing_method_on_nil
Mocha.configure { |c| c.stubbing_method_on_nil = :warn }
test_result = run_as_test do
nil.stubs(:stubbed_method)
end
assert_passed(test_result)
assert @logger.warnings.include?('stubbing method on nil: nil.stubbed_method')
def potential_violation
nil.stubs(:stubbed_method)
end

def test_should_prevent_stubbing_method_on_nil
Mocha.configure { |c| c.stubbing_method_on_nil = :prevent }
test_result = run_as_test do
nil.stubs(:stubbed_method)
end
assert_failed(test_result)
assert test_result.error_messages.include?('Mocha::StubbingError: stubbing method on nil: nil.stubbed_method')
def message_on_violation
'stubbing method on nil: nil.stubbed_method'
end

def test_should_default_to_prevent_stubbing_method_on_non_mock_object
test_result = run_as_test do
nil.stubs(:stubbed_method)
end
def test_should_default_to_prevent_stubbing_method_on_nil
test_result = stub_with_potential_violation
assert_failed(test_result)
assert test_result.error_messages.include?('Mocha::StubbingError: stubbing method on nil: nil.stubbed_method')
assert test_result.error_messages.include?("Mocha::StubbingError: #{message_on_violation}")
end

def test_should_allow_stubbing_method_on_non_nil_object
Mocha.configure { |c| c.stubbing_method_on_nil = :prevent }
object = Object.new
test_result = run_as_test do
object.stubs(:stubbed_method)
test_result = run_test_with_check(:prevent) do
Object.new.stubs(:stubbed_method)
end
assert_passed(test_result)
end
Expand Down
148 changes: 18 additions & 130 deletions test/acceptance/stubbing_non_existent_any_instance_method_test.rb
Original file line number Diff line number Diff line change
@@ -1,80 +1,15 @@
require File.expand_path('../acceptance_test_helper', __FILE__)
require 'mocha/configuration'
require File.expand_path('../stubbing_non_existent_method_is_checked', __FILE__)
require File.expand_path('../stubbing_existing_method_is_allowed', __FILE__)
require File.expand_path('../stubbing_any_instance_method', __FILE__)

class StubbingNonExistentAnyInstanceMethodTest < Mocha::TestCase
include AcceptanceTest

def setup
setup_acceptance_test
end

def teardown
teardown_acceptance_test
end

def test_should_allow_stubbing_non_existent_any_instance_method
Mocha.configure { |c| c.stubbing_non_existent_method = :allow }
klass = Class.new
test_result = run_as_test do
klass.any_instance.stubs(:non_existent_method)
end
assert !@logger.warnings.include?("stubbing non-existent method: #{klass.any_instance.mocha_inspect}.non_existent_method")
assert_passed(test_result)
end

def test_should_warn_when_stubbing_non_existent_any_instance_method
Mocha.configure { |c| c.stubbing_non_existent_method = :warn }
klass = Class.new
test_result = run_as_test do
klass.any_instance.stubs(:non_existent_method)
end
assert_passed(test_result)
assert @logger.warnings.include?("stubbing non-existent method: #{klass.any_instance.mocha_inspect}.non_existent_method")
end

def test_should_prevent_stubbing_non_existent_any_instance_method
Mocha.configure { |c| c.stubbing_non_existent_method = :prevent }
klass = Class.new
test_result = run_as_test do
klass.any_instance.stubs(:non_existent_method)
end
assert_failed(test_result)
assert test_result.error_messages.include?("Mocha::StubbingError: stubbing non-existent method: #{klass.any_instance.mocha_inspect}.non_existent_method")
end

def test_should_default_to_allow_stubbing_non_existent_any_instance_method
klass = Class.new
test_result = run_as_test do
klass.any_instance.stubs(:non_existent_method)
end
assert !@logger.warnings.include?("stubbing non-existent method: #{klass.any_instance.mocha_inspect}.non_existent_method")
assert_passed(test_result)
end
include StubbingNonExistentMethodIsChecked
include StubbingAnyInstanceMethod
end

def test_should_allow_stubbing_existing_public_any_instance_method
Mocha.configure { |c| c.stubbing_non_existent_method = :prevent }
klass = Class.new do
def existing_public_method; end
public :existing_public_method
end
test_result = run_as_test do
klass.any_instance.stubs(:existing_public_method)
end
assert_passed(test_result)
end

def test_should_allow_stubbing_method_to_which_any_instance_responds
Mocha.configure { |c| c.stubbing_non_existent_method = :prevent }
klass = Class.new do
def respond_to?(method, _include_private = false)
(method == :method_to_which_instance_responds)
end
end
test_result = run_as_test do
klass.any_instance.stubs(:method_to_which_instance_responds)
end
assert_passed(test_result)
end
class StubbingExistingAnyInstanceMethodIsAllowedTest < Mocha::TestCase
include StubbingExistingMethodIsAllowed
include StubbingAnyInstanceMethod

def test_should_default_to_allowing_stubbing_method_if_responds_to_depends_on_calling_initialize
klass = Class.new do
Expand All @@ -91,67 +26,20 @@ def respond_to?(method, _include_private = false)
end
assert_passed(test_result)
end
end

def test_should_allow_stubbing_existing_protected_any_instance_method
Mocha.configure { |c| c.stubbing_non_existent_method = :prevent }
klass = Class.new do
def existing_protected_method; end
protected :existing_protected_method
end
test_result = run_as_test do
klass.any_instance.stubs(:existing_protected_method)
end
assert_passed(test_result)
end

def test_should_allow_stubbing_existing_private_any_instance_method
Mocha.configure { |c| c.stubbing_non_existent_method = :prevent }
klass = Class.new do
def existing_private_method; end
private :existing_private_method
end
test_result = run_as_test do
klass.any_instance.stubs(:existing_private_method)
end
assert_passed(test_result)
end
class StubbingExistingAnyInstanceSuperclassMethodIsAllowedTest < Mocha::TestCase
include StubbingExistingMethodIsAllowed

def test_should_allow_stubbing_existing_public_any_instance_superclass_method
Mocha.configure { |c| c.stubbing_non_existent_method = :prevent }
superklass = Class.new do
def existing_public_method; end
public :existing_public_method
end
klass = Class.new(superklass)
test_result = run_as_test do
klass.any_instance.stubs(:existing_public_method)
end
assert_passed(test_result)
def method_owner
callee.superclass
end

def test_should_allow_stubbing_existing_protected_any_instance_superclass_method
Mocha.configure { |c| c.stubbing_non_existent_method = :prevent }
superklass = Class.new do
def existing_protected_method; end
protected :existing_protected_method
end
klass = Class.new(superklass)
test_result = run_as_test do
klass.any_instance.stubs(:existing_protected_method)
end
assert_passed(test_result)
def stubbee
callee.any_instance
end

def test_should_allow_stubbing_existing_private_any_instance_superclass_method
Mocha.configure { |c| c.stubbing_non_existent_method = :prevent }
superklass = Class.new do
def existing_private_method; end
private :existing_private_method
end
klass = Class.new(superklass)
test_result = run_as_test do
klass.any_instance.stubs(:existing_private_method)
end
assert_passed(test_result)
def callee
@callee ||= Class.new(Class.new)
end
end