summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--spec/mspec/lib/mspec/helpers/frozen_error_class.rb2
-rw-r--r--spec/mspec/lib/mspec/mocks/mock.rb20
-rw-r--r--spec/mspec/spec/mocks/mock_spec.rb65
3 files changed, 82 insertions, 5 deletions
diff --git a/spec/mspec/lib/mspec/helpers/frozen_error_class.rb b/spec/mspec/lib/mspec/helpers/frozen_error_class.rb
index 26788ad9ad..07cc2b4ba2 100644
--- a/spec/mspec/lib/mspec/helpers/frozen_error_class.rb
+++ b/spec/mspec/lib/mspec/helpers/frozen_error_class.rb
@@ -2,7 +2,7 @@ require 'mspec/guards/version'
# This helper makes it easy to write version independent
# specs for frozen objects.
-unless respond_to? :frozen_error_class
+unless respond_to? :frozen_error_class, true
ruby_version_is "2.5" do
def frozen_error_class
FrozenError
diff --git a/spec/mspec/lib/mspec/mocks/mock.rb b/spec/mspec/lib/mspec/mocks/mock.rb
index b11d469186..cb4875bbd6 100644
--- a/spec/mspec/lib/mspec/mocks/mock.rb
+++ b/spec/mspec/lib/mspec/mocks/mock.rb
@@ -54,6 +54,11 @@ module Mock
key = replaced_key obj, sym
sym = sym.to_sym
+ if type == :stub and mocks.key?(key)
+ # Defining a stub and there is already a mock, ignore the stub
+ return
+ end
+
if (sym == :respond_to? or mock_respond_to?(obj, sym, true)) and !replaced?(key.first)
meta.__send__ :alias_method, key.first, sym
end
@@ -73,6 +78,11 @@ module Mock
MSpec.actions :expectation, MSpec.current.state
end
+ if proxy.mock? and stubs.key?(key)
+ # Defining a mock and there is already a stub, remove the stub
+ stubs.delete key
+ end
+
if proxy.stub?
stubs[key].unshift proxy
else
@@ -87,6 +97,10 @@ module Mock
obj.instance_variable_get(:@name) || obj.inspect
end
+ def self.inspect_args(args)
+ "(#{Array(args).map(&:inspect).join(', ')})"
+ end
+
def self.verify_count
mocks.each do |key, proxies|
obj = objects[key]
@@ -106,7 +120,7 @@ module Mock
end
unless pass
SpecExpectation.fail_with(
- "Mock '#{name_or_inspect obj}' expected to receive '#{key.last}' " + \
+ "Mock '#{name_or_inspect obj}' expected to receive #{key.last}#{inspect_args proxy.arguments} " + \
"#{qualifier.to_s.sub('_', ' ')} #{count} times",
"but received it #{proxy.calls} times")
end
@@ -120,7 +134,7 @@ module Mock
key = replaced_key obj, sym
[mocks, stubs].each do |proxies|
- proxies[key].each do |proxy|
+ proxies.fetch(key, []).each do |proxy|
pass = case proxy.arguments
when :any_args
true
@@ -166,7 +180,7 @@ module Mock
mock_respond_to? obj, *args
else
SpecExpectation.fail_with("Mock '#{name_or_inspect obj}': method #{sym}\n",
- "called with unexpected arguments (#{Array(compare).join(' ')})")
+ "called with unexpected arguments #{inspect_args compare}")
end
end
diff --git a/spec/mspec/spec/mocks/mock_spec.rb b/spec/mspec/spec/mocks/mock_spec.rb
index c814ec7bfe..8cf04cf462 100644
--- a/spec/mspec/spec/mocks/mock_spec.rb
+++ b/spec/mspec/spec/mocks/mock_spec.rb
@@ -313,6 +313,58 @@ describe Mock, ".verify_call" do
end
end
+describe Mock, ".verify_call mixing mocks and stubs" do
+ before :each do
+ MSpec.stub(:actions)
+ MSpec.stub(:current).and_return(double("spec state").as_null_object)
+
+ @mock = double('verify_call')
+ end
+
+ after :each do
+ ScratchPad.clear
+ Mock.cleanup
+ end
+
+ it "checks the mock arguments when a mock is defined after a stub" do
+ Mock.install_method @mock, :method_call, :stub
+ Mock.install_method(@mock, :method_call, :mock).with("arg")
+
+ -> {
+ @mock.method_call
+ }.should raise_error(SpecExpectationNotMetError, /called with unexpected arguments \(\)/)
+
+ -> {
+ @mock.method_call("a", "b")
+ }.should raise_error(SpecExpectationNotMetError, /called with unexpected arguments \("a", "b"\)/)
+
+ -> {
+ @mock.method_call("foo")
+ }.should raise_error(SpecExpectationNotMetError, /called with unexpected arguments \("foo"\)/)
+
+ @mock.method_call("arg")
+ end
+
+ it "checks the mock arguments when a stub is defined after a mock" do
+ Mock.install_method(@mock, :method_call, :mock).with("arg")
+ Mock.install_method @mock, :method_call, :stub
+
+ -> {
+ @mock.method_call
+ }.should raise_error(SpecExpectationNotMetError, /called with unexpected arguments \(\)/)
+
+ -> {
+ @mock.method_call("a", "b")
+ }.should raise_error(SpecExpectationNotMetError, /called with unexpected arguments \("a", "b"\)/)
+
+ -> {
+ @mock.method_call("foo")
+ }.should raise_error(SpecExpectationNotMetError, /called with unexpected arguments \("foo"\)/)
+
+ @mock.method_call("arg")
+ end
+end
+
describe Mock, ".verify_count" do
before :each do
MSpec.stub(:actions)
@@ -396,6 +448,11 @@ describe Mock, ".verify_count mixing mocks and stubs" do
it "verifies the calls to the mocked method when a mock is defined after a stub" do
Mock.install_method @mock, :method_call, :stub
Mock.install_method @mock, :method_call, :mock
+
+ -> {
+ Mock.verify_count
+ }.should raise_error(SpecExpectationNotMetError, /received it 0 times/)
+
@mock.method_call
Mock.verify_count
end
@@ -403,6 +460,11 @@ describe Mock, ".verify_count mixing mocks and stubs" do
it "verifies the calls to the mocked method when a mock is defined before a stub" do
Mock.install_method @mock, :method_call, :mock
Mock.install_method @mock, :method_call, :stub
+
+ -> {
+ Mock.verify_count
+ }.should raise_error(SpecExpectationNotMetError, /received it 0 times/)
+
@mock.method_call
Mock.verify_count
end
@@ -415,7 +477,6 @@ describe Mock, ".cleanup" do
@mock = double('cleanup')
@proxy = Mock.install_method @mock, :method_call
- @stub = Mock.install_method @mock, :method_call, :stub
end
after :each do
@@ -449,6 +510,8 @@ describe Mock, ".cleanup" do
end
it "removes all stubs" do
+ Mock.cleanup # remove @proxy
+ @stub = Mock.install_method @mock, :method_call, :stub
Mock.stubs.should == { Mock.replaced_key(@mock, :method_call) => [@stub] }
Mock.cleanup
Mock.stubs.should == {}