Convert from Mocha to RSpec Mocks

This commit is contained in:
Elliot Winkler 2014-11-07 15:22:20 -07:00
parent dca7c96bc9
commit 3a76f9389f
17 changed files with 158 additions and 82 deletions

View File

@ -3,10 +3,11 @@ require 'unit_spec_helper'
describe Shoulda::Matchers::ActiveModel do describe Shoulda::Matchers::ActiveModel do
describe '#ensure_length_of' do describe '#ensure_length_of' do
it 'is aliased to #validate_length_of' do it 'is aliased to #validate_length_of' do
matchers.expects(:validate_length_of).with(:attr) allow(matchers).to receive(:validate_length_of)
silence_warnings do silence_warnings do
matchers.ensure_length_of(:attr) matchers.ensure_length_of(:attr)
expect(matchers).to have_received(:validate_length_of).with(:attr)
end end
end end
end end

View File

@ -47,56 +47,56 @@ describe Shoulda::Matchers::ActionController::SetSessionMatcher do
end end
it 'accepts assigning to the same value in the test context' do it 'accepts assigning to the same value in the test context' do
context = stub(expected: 'value') context = double(expected: 'value')
expect(controller_with_session(var: 'value')). expect(controller_with_session(var: 'value')).
to set_session(:var).in_context(context).to { expected } to set_session(:var).in_context(context).to { expected }
end end
it 'rejects assigning to the another value in the test context' do it 'rejects assigning to the another value in the test context' do
context = stub(expected: 'other') context = double(expected: 'other')
expect(controller_with_session(var: 'unexpected')). expect(controller_with_session(var: 'unexpected')).
not_to set_session(:var).in_context(context).to { expected } not_to set_session(:var).in_context(context).to { expected }
end end
it 'accepts assigning nil to another variable in the test context' do it 'accepts assigning nil to another variable in the test context' do
context = stub(expected: nil) context = double(expected: nil)
expect(controller_with_session(var: 'hi')). expect(controller_with_session(var: 'hi')).
to set_session(:other).in_context(context).to { expected } to set_session(:other).in_context(context).to { expected }
end end
it 'rejects assigning nil to that variable in the test context' do it 'rejects assigning nil to that variable in the test context' do
context = stub(expected: nil) context = double(expected: nil)
expect(controller_with_session(var: 'hi')). expect(controller_with_session(var: 'hi')).
not_to set_session(:var).in_context(context).to { expected } not_to set_session(:var).in_context(context).to { expected }
end end
it 'accepts assigning nil to a cleared variable in the test context' do it 'accepts assigning nil to a cleared variable in the test context' do
context = stub(expected: nil) context = double(expected: nil)
expect(controller_with_session(var: nil)). expect(controller_with_session(var: nil)).
to set_session(:var).in_context(context).to { expected } to set_session(:var).in_context(context).to { expected }
end end
it 'accepts assigning false to that variable in the test context' do it 'accepts assigning false to that variable in the test context' do
context = stub(expected: false) context = double(expected: false)
expect(controller_with_session(var: false)). expect(controller_with_session(var: false)).
to set_session(:var).in_context(context).to { expected } to set_session(:var).in_context(context).to { expected }
end end
it 'accepts assigning false to other variable in the test context' do it 'accepts assigning false to other variable in the test context' do
context = stub(expected: false) context = double(expected: false)
expect(controller_with_session(var: false)). expect(controller_with_session(var: false)).
not_to set_session(:other).in_context(context).to { expected } not_to set_session(:other).in_context(context).to { expected }
end end
it 'accepts assigning false to other variable in the test context' do it 'accepts assigning false to other variable in the test context' do
context = stub(expected: false) context = double(expected: false)
expect(controller_with_session(var: 'hi')). expect(controller_with_session(var: 'hi')).
not_to set_session(:var).in_context(context).to { expected } not_to set_session(:var).in_context(context).to { expected }

View File

@ -261,11 +261,12 @@ describe Shoulda::Matchers::ActionController::StrongParametersMatcher do
context 'when given :create' do context 'when given :create' do
it 'POSTs to the controller' do it 'POSTs to the controller' do
controller = ActionController::Base.new controller = ActionController::Base.new
context = mock() context = build_context
context.expects(:post).with(:create, {})
matcher = described_class.new([:name]).in_context(context).for(:create) matcher = described_class.new([:name]).in_context(context).for(:create)
matcher.matches?(controller) matcher.matches?(controller)
expect(context).to have_received(:post).with(:create, {})
end end
end end
@ -273,20 +274,22 @@ describe Shoulda::Matchers::ActionController::StrongParametersMatcher do
if rails_gte_4_1? if rails_gte_4_1?
it 'PATCHes to the controller' do it 'PATCHes to the controller' do
controller = ActionController::Base.new controller = ActionController::Base.new
context = mock() context = build_context
context.expects(:patch).with(:update, {})
matcher = described_class.new([:name]).in_context(context).for(:update) matcher = described_class.new([:name]).in_context(context).for(:update)
matcher.matches?(controller) matcher.matches?(controller)
expect(context).to have_received(:patch).with(:update, {})
end end
else else
it 'PUTs to the controller' do it 'PUTs to the controller' do
controller = ActionController::Base.new controller = ActionController::Base.new
context = mock() context = build_context
context.expects(:put).with(:update, {})
matcher = described_class.new([:name]).in_context(context).for(:update) matcher = described_class.new([:name]).in_context(context).for(:update)
matcher.matches?(controller) matcher.matches?(controller)
expect(context).to have_received(:put).with(:update, {})
end end
end end
end end
@ -294,13 +297,14 @@ describe Shoulda::Matchers::ActionController::StrongParametersMatcher do
context 'when given a custom action and verb' do context 'when given a custom action and verb' do
it 'calls the action with the verb' do it 'calls the action with the verb' do
controller = ActionController::Base.new controller = ActionController::Base.new
context = mock() context = build_context
context.expects(:delete).with(:hide, {})
matcher = described_class.new([:name]). matcher = described_class.new([:name]).
in_context(context). in_context(context).
for(:hide, verb: :delete) for(:hide, verb: :delete)
matcher.matches?(controller) matcher.matches?(controller)
expect(context).to have_received(:delete).with(:hide, {})
end end
end end
end end
@ -319,5 +323,9 @@ describe Shoulda::Matchers::ActionController::StrongParametersMatcher do
end end
end end
def build_context
double('context', post: nil, put: nil, patch: nil, delete: nil)
end
class SimulatedError < StandardError; end class SimulatedError < StandardError; end
end end

View File

@ -36,8 +36,12 @@ describe Shoulda::Matchers::ActiveModel::DisallowValueMatcher do
end end
it "delegates its failure message to its allow matcher's negative failure message" do it "delegates its failure message to its allow matcher's negative failure message" do
allow_matcher = stub_everything(failure_message_when_negated: 'allow matcher failure') allow_matcher = double('allow_matcher',
Shoulda::Matchers::ActiveModel::AllowValueMatcher.stubs(:new).returns(allow_matcher) failure_message_when_negated: 'allow matcher failure',
).as_null_object
allow(Shoulda::Matchers::ActiveModel::AllowValueMatcher).
to receive(:new).
and_return(allow_matcher)
matcher = matcher('abcde').for(:attr).with_message('good message') matcher = matcher('abcde').for(:attr).with_message('good message')
matcher.matches?(validating_format(with: /abc/, message: 'good message')) matcher.matches?(validating_format(with: /abc/, message: 'good message'))

View File

@ -153,6 +153,10 @@ describe Shoulda::Matchers::ActiveModel::Helpers do
message = options.delete(:message) message = options.delete(:message)
type = options.delete(:type) type = options.delete(:type)
ActiveModel::Errors.any_instance.expects(:generate_message).with(attribute, type, {}).at_least_once.returns(message) expect_any_instance_of(ActiveModel::Errors).
to receive(:generate_message).
with(attribute, type, {}).
at_least(1).
and_return(message)
end end
end end

View File

@ -3,10 +3,11 @@ require 'unit_spec_helper'
describe Shoulda::Matchers::ActiveModel do describe Shoulda::Matchers::ActiveModel do
describe '#ensure_exclusion_of' do describe '#ensure_exclusion_of' do
it 'is aliased to #validate_exclusion_of' do it 'is aliased to #validate_exclusion_of' do
matchers.expects(:validate_exclusion_of).with(:attr) allow(matchers).to receive(:validate_exclusion_of)
silence_warnings do silence_warnings do
matchers.ensure_exclusion_of(:attr) matchers.ensure_exclusion_of(:attr)
expect(matchers).to have_received(:validate_exclusion_of).with(:attr)
end end
end end
end end

View File

@ -3,10 +3,11 @@ require 'unit_spec_helper'
describe Shoulda::Matchers::ActiveModel do describe Shoulda::Matchers::ActiveModel do
describe '#ensure_inclusion_of' do describe '#ensure_inclusion_of' do
it 'is aliased to #validate_inclusion_of' do it 'is aliased to #validate_inclusion_of' do
matchers.expects(:validate_inclusion_of).with(:attr) allow(matchers).to receive(:validate_inclusion_of)
silence_warnings do silence_warnings do
matchers.ensure_inclusion_of(:attr) matchers.ensure_inclusion_of(:attr)
expect(matchers).to have_received(:validate_inclusion_of)
end end
end end
end end

View File

@ -278,7 +278,7 @@ describe Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher do
def set_attr!; self.attr = 5 end def set_attr!; self.attr = 5 end
end.new end.new
subject.stubs(:set_attr!) allow(subject).to receive(:set_attr!)
expect(subject).to matcher.odd expect(subject).to matcher.odd
end end
end end

View File

@ -7,7 +7,7 @@ describe Shoulda::Matchers::ActiveRecord::AssociationMatchers::ModelReflection d
belongs_to :country belongs_to :country
end end
delegate_reflection = person_model.reflect_on_association(:country) delegate_reflection = person_model.reflect_on_association(:country)
delegate_reflection.stubs(foo: 'bar') allow(delegate_reflection).to receive(:foo).and_return('bar')
reflection = described_class.new(delegate_reflection) reflection = described_class.new(delegate_reflection)
expect(reflection.foo).to eq 'bar' expect(reflection.foo).to eq 'bar'

View File

@ -65,10 +65,13 @@ describe Shoulda::Matchers::ActiveRecord::HaveDbIndexMatcher do
end end
it 'allows an IndexDefinition to have a truthy value for unique' do it 'allows an IndexDefinition to have a truthy value for unique' do
index_definition = stub('ActiveRecord::ConnectionAdapters::IndexDefinition', index_definition = double(
unique: 7, name: :age) 'ActiveRecord::ConnectionAdapters::IndexDefinition',
unique: 7,
name: :age
)
matcher = have_db_index(:age).unique(true) matcher = have_db_index(:age).unique(true)
matcher.stubs(matched_index: index_definition) allow(matcher).to receive(:matched_index).and_return(index_definition)
expect(with_index_on(:age)).to matcher expect(with_index_on(:age)).to matcher
end end

View File

@ -4,31 +4,53 @@ module Shoulda::Matchers::Doublespeak
describe DoubleCollection do describe DoubleCollection do
describe '#register_stub' do describe '#register_stub' do
it 'calls DoubleImplementationRegistry.find correctly' do it 'calls DoubleImplementationRegistry.find correctly' do
allow(DoubleImplementationRegistry).to receive(:find)
double_collection = described_class.new(:klass) double_collection = described_class.new(:klass)
DoubleImplementationRegistry.expects(:find).with(:stub)
double_collection.register_stub(:a_method) double_collection.register_stub(:a_method)
expect(DoubleImplementationRegistry).to have_received(:find).with(:stub)
end end
it 'calls Double.new correctly' do it 'calls Double.new correctly' do
DoubleImplementationRegistry.stubs(:find).returns(:implementation) allow(DoubleImplementationRegistry).
to receive(:find).
and_return(:implementation)
allow(Double).to receive(:new)
double_collection = described_class.new(:klass) double_collection = described_class.new(:klass)
Double.expects(:new).with(:klass, :a_method, :implementation)
double_collection.register_stub(:a_method) double_collection.register_stub(:a_method)
expect(Double).
to have_received(:new).
with(:klass, :a_method, :implementation)
end end
end end
describe '#register_proxy' do describe '#register_proxy' do
it 'calls DoubleImplementationRegistry.find correctly' do it 'calls DoubleImplementationRegistry.find correctly' do
allow(DoubleImplementationRegistry).to receive(:find)
double_collection = described_class.new(:klass) double_collection = described_class.new(:klass)
DoubleImplementationRegistry.expects(:find).with(:proxy)
double_collection.register_proxy(:a_method) double_collection.register_proxy(:a_method)
expect(DoubleImplementationRegistry).
to have_received(:find).
with(:proxy)
end end
it 'calls Double.new correctly' do it 'calls Double.new correctly' do
DoubleImplementationRegistry.stubs(:find).returns(:implementation) allow(DoubleImplementationRegistry).
to receive(:find).
and_return(:implementation)
allow(Double).to receive(:new)
double_collection = described_class.new(:klass) double_collection = described_class.new(:klass)
Double.expects(:new).with(:klass, :a_method, :implementation)
double_collection.register_proxy(:a_method) double_collection.register_proxy(:a_method)
expect(Double).
to have_received(:new).
with(:klass, :a_method, :implementation)
end end
end end

View File

@ -6,7 +6,8 @@ module Shoulda::Matchers::Doublespeak
it 'tells its implementation to call the given block' do it 'tells its implementation to call the given block' do
sent_block = -> { } sent_block = -> { }
actual_block = nil actual_block = nil
implementation = stub implementation = build_implementation
implementation.singleton_class.__send__(:undef_method, :returns)
implementation.singleton_class.__send__(:define_method, :returns) do |&block| implementation.singleton_class.__send__(:define_method, :returns) do |&block|
actual_block = block actual_block = block
end end
@ -16,16 +17,18 @@ module Shoulda::Matchers::Doublespeak
end end
it 'tells its implementation to return the given value' do it 'tells its implementation to return the given value' do
implementation = mock() implementation = build_implementation
implementation.expects(:returns).with(:implementation)
double = described_class.new(:klass, :a_method, implementation) double = described_class.new(:klass, :a_method, implementation)
double.to_return(:implementation) double.to_return(:implementation)
expect(implementation).to have_received(:returns).with(:implementation)
end end
it 'prefers a block over a non-block' do it 'prefers a block over a non-block' do
sent_block = -> { } sent_block = -> { }
actual_block = nil actual_block = nil
implementation = stub implementation = build_implementation
implementation.singleton_class.__send__(:undef_method, :returns)
implementation.singleton_class.__send__(:define_method, :returns) do |&block| implementation.singleton_class.__send__(:define_method, :returns) do |&block|
actual_block = block actual_block = block
end end
@ -37,22 +40,25 @@ module Shoulda::Matchers::Doublespeak
describe '#activate' do describe '#activate' do
it 'replaces the method with an implementation' do it 'replaces the method with an implementation' do
implementation = stub implementation = build_implementation
klass = create_class(a_method: 42) klass = create_class(a_method: 42)
instance = klass.new instance = klass.new
double = described_class.new(klass, :a_method, implementation) double = described_class.new(klass, :a_method, implementation)
args = [:any, :args] args = [:any, :args]
block = -> {} block = -> {}
implementation.expects(:call).with(double, instance, args, block)
double.activate double.activate
instance.a_method(*args, &block) instance.a_method(*args, &block)
expect(implementation).
to have_received(:call).
with(double, instance, args, block)
end end
end end
describe '#deactivate' do describe '#deactivate' do
it 'restores the original method after being doubled' do it 'restores the original method after being doubled' do
implementation = stub(call: nil) implementation = build_implementation
klass = create_class(a_method: 42) klass = create_class(a_method: 42)
instance = klass.new instance = klass.new
double = described_class.new(klass, :a_method, implementation) double = described_class.new(klass, :a_method, implementation)
@ -63,7 +69,7 @@ module Shoulda::Matchers::Doublespeak
end end
it 'still restores the original method if #activate was called twice' do it 'still restores the original method if #activate was called twice' do
implementation = stub(call: nil) implementation = build_implementation
klass = create_class(a_method: 42) klass = create_class(a_method: 42)
instance = klass.new instance = klass.new
double = described_class.new(klass, :a_method, implementation) double = described_class.new(klass, :a_method, implementation)
@ -75,7 +81,7 @@ module Shoulda::Matchers::Doublespeak
end end
it 'does nothing if the method has not been doubled' do it 'does nothing if the method has not been doubled' do
implementation = stub(call: nil) implementation = build_implementation
klass = create_class(a_method: 42) klass = create_class(a_method: 42)
instance = klass.new instance = klass.new
double = described_class.new(klass, :a_method, implementation) double = described_class.new(klass, :a_method, implementation)
@ -140,5 +146,9 @@ module Shoulda::Matchers::Doublespeak
end end
end end
end end
def build_implementation
double('implementation', returns: nil, call: nil)
end
end end
end end

View File

@ -5,9 +5,10 @@ module Shoulda::Matchers::Doublespeak
describe '#returns' do describe '#returns' do
it 'delegates to its stub_implementation' do it 'delegates to its stub_implementation' do
stub_implementation = build_stub_implementation stub_implementation = build_stub_implementation
stub_implementation.expects(:returns).with(:value)
implementation = described_class.new(stub_implementation) implementation = described_class.new(stub_implementation)
implementation.returns(:value) implementation.returns(:value)
expect(stub_implementation).to have_received(:returns).with(:value)
end end
end end
@ -15,26 +16,32 @@ module Shoulda::Matchers::Doublespeak
it 'delegates to its stub_implementation' do it 'delegates to its stub_implementation' do
stub_implementation = build_stub_implementation stub_implementation = build_stub_implementation
double = build_double double = build_double
stub_implementation.expects(:call).with(double, :object, :args, :block)
implementation = described_class.new(stub_implementation) implementation = described_class.new(stub_implementation)
implementation.call(double, :object, :args, :block) implementation.call(double, :object, :args, :block)
expect(stub_implementation).
to have_received(:call).
with(double, :object, :args, :block)
end end
it 'calls #call_original_method on the double' do it 'calls #call_original_method on the double' do
stub_implementation = build_stub_implementation stub_implementation = build_stub_implementation
implementation = described_class.new(stub_implementation) implementation = described_class.new(stub_implementation)
double = build_double double = build_double
double.expects(:call_original_method).with(:object, :args, :block)
implementation.call(double, :object, :args, :block) implementation.call(double, :object, :args, :block)
expect(double).
to have_received(:call_original_method).
with(:object, :args, :block)
end end
end end
def build_stub_implementation def build_stub_implementation
stub(returns: nil, call: nil) double('stub_implementation', returns: nil, call: nil)
end end
def build_double def build_double
stub(call_original_method: nil) double('double', call_original_method: nil)
end end
end end
end end

View File

@ -82,7 +82,7 @@ module Shoulda::Matchers::Doublespeak
end end
def build_double def build_double
stub(record_call: nil) double('double', record_call: nil)
end end
end end
end end

View File

@ -4,16 +4,23 @@ module Shoulda::Matchers::Doublespeak
describe World do describe World do
describe '#double_collection_for' do describe '#double_collection_for' do
it 'calls DoubleCollection.new once with the given class' do it 'calls DoubleCollection.new once with the given class' do
DoubleCollection.expects(:new).with(:klass).returns(:klass).once allow(DoubleCollection).to receive(:new).and_return(:klass)
world = described_class.new world = described_class.new
world.double_collection_for(:klass) world.double_collection_for(:klass)
world.double_collection_for(:klass) world.double_collection_for(:klass)
expect(DoubleCollection).to have_received(:new).with(:klass).once
end end
it 'returns the created DoubleCollection' do it 'returns the created DoubleCollection' do
double_collection = Object.new double_collection = build_double_collection
DoubleCollection.stubs(:new).with(:klass).returns(double_collection) allow(DoubleCollection).
to receive(:new).
with(:klass).
and_return(double_collection)
world = described_class.new world = described_class.new
expect(world.double_collection_for(:klass)).to be double_collection expect(world.double_collection_for(:klass)).to be double_collection
end end
end end
@ -21,50 +28,50 @@ module Shoulda::Matchers::Doublespeak
describe '#with_doubles_activated' do describe '#with_doubles_activated' do
it 'installs all doubles, yields the block, then uninstalls them all' do it 'installs all doubles, yields the block, then uninstalls them all' do
block_called = false block_called = false
double_collections = Array.new(3) { build_double_collection }
double_collections = Array.new(3) do double_collections.each do |double_collection|
stub.tap do |double_collection| allow(double_collection).to receive(:activate).ordered
sequence = sequence('with_doubles_activated')
double_collection.expects(:activate).in_sequence(sequence)
double_collection.expects(:deactivate).in_sequence(sequence)
end
end end
double_collections.each do |double_collection|
allow(double_collection).to receive(:deactivate).ordered
end
klasses = Array.new(3) { |i| "Klass #{i}" }
world = described_class.new world = described_class.new
double_collections.zip(klasses).each do |double_collection, klass|
DoubleCollection.stubs(:new). allow(DoubleCollection).
with(:klass1). to receive(:new).
returns(double_collections[0]) with(klass).
DoubleCollection.stubs(:new). and_return(double_collection)
with(:klass2). world.double_collection_for(klass)
returns(double_collections[1]) end
DoubleCollection.stubs(:new).
with(:klass3).
returns(double_collections[2])
world.double_collection_for(:klass1)
world.double_collection_for(:klass2)
world.double_collection_for(:klass3)
world.with_doubles_activated { block_called = true } world.with_doubles_activated { block_called = true }
expect(block_called).to eq true expect(block_called).to eq true
double_collections.each do |double_collection|
expect(double_collection).to have_received(:activate)
expect(double_collection).to have_received(:deactivate)
end
end end
it 'still makes sure to uninstall all doubles even if the block raises an error' do it 'still makes sure to uninstall all doubles even if the block raises an error' do
double_collection = stub() double_collection = build_double_collection
double_collection.stubs(:activate) allow(DoubleCollection).to receive(:new).and_return(double_collection)
double_collection.expects(:deactivate)
world = described_class.new world = described_class.new
DoubleCollection.stubs(:new).returns(double_collection)
world.double_collection_for(:klass) world.double_collection_for(:klass)
begin begin
world.with_doubles_activated { raise 'error' } world.with_doubles_activated { raise 'error' }
rescue RuntimeError rescue RuntimeError
end end
expect(double_collection).to have_received(:deactivate)
end end
end end
def build_double_collection
double('double_collection', activate: nil, deactivate: nil)
end
end end
end end

View File

@ -4,15 +4,23 @@ module Shoulda::Matchers
describe Doublespeak do describe Doublespeak do
describe '.double_collection_for' do describe '.double_collection_for' do
it 'delegates to its world' do it 'delegates to its world' do
Doublespeak.world.expects(:double_collection_for).with(:klass) allow(Doublespeak.world).to receive(:double_collection_for)
described_class.double_collection_for(:klass) described_class.double_collection_for(:klass)
expect(Doublespeak.world).
to have_received(:double_collection_for).
with(:klass)
end end
end end
describe '.with_doubles_activated' do describe '.with_doubles_activated' do
it 'delegates to its world' do it 'delegates to its world' do
Doublespeak.world.expects(:with_doubles_activated) allow(Doublespeak.world).to receive(:with_doubles_activated)
described_class.with_doubles_activated described_class.with_doubles_activated
expect(Doublespeak.world).to have_received(:with_doubles_activated)
end end
end end
end end

View File

@ -22,7 +22,6 @@ monkey_patch_minitest_to_do_nothing
ENV['BUNDLE_GEMFILE'] ||= app.gemfile_path ENV['BUNDLE_GEMFILE'] ||= app.gemfile_path
ENV['RAILS_ENV'] = 'test' ENV['RAILS_ENV'] = 'test'
require 'bourne'
require 'shoulda-matchers' require 'shoulda-matchers'
require 'rspec/rails' require 'rspec/rails'
@ -40,11 +39,12 @@ RSpec.configure do |config|
c.syntax = :expect c.syntax = :expect
end end
config.mock_with :rspec
if config.respond_to?(:infer_spec_type_from_file_location!) if config.respond_to?(:infer_spec_type_from_file_location!)
config.infer_spec_type_from_file_location! config.infer_spec_type_from_file_location!
end end
config.mock_with :mocha
config.include Shoulda::Matchers::ActionController, type: :controller config.include Shoulda::Matchers::ActionController, type: :controller
UnitTests::ActiveModelHelpers.configure_example_group(config) UnitTests::ActiveModelHelpers.configure_example_group(config)