bogus 0.0.2 → 0.0.3.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +2 -0
- data/Gemfile.lock +14 -2
- data/Guardfile +5 -0
- data/README.md +7 -249
- data/bogus.gemspec +3 -1
- data/features/.nav +21 -0
- data/features/authors.md +42 -0
- data/{CHANGELOG.md → features/changelog.md} +9 -2
- data/features/configuration_options.feature +1 -2
- data/features/{contract_tests_mocks.feature → contract_tests/contract_tests_mocks.feature} +4 -1
- data/features/{contract_tests_spies.feature → contract_tests/contract_tests_spies.feature} +2 -0
- data/features/{contract_tests_stubs.feature → contract_tests/contract_tests_stubs.feature} +14 -0
- data/features/contract_tests/readme.md +26 -0
- data/features/{return_value_contracts.feature → contract_tests/return_value_contracts.feature} +6 -2
- data/features/{anonymous_doubles.feature → fakes/anonymous_doubles.feature} +24 -8
- data/features/{fake_objects.feature → fakes/fake_objects.feature} +39 -4
- data/features/fakes/global_fake_configuration.feature +88 -0
- data/features/fakes/readme.md +11 -0
- data/features/fakes/replacing_classes.feature +148 -0
- data/features/getting_started.md +36 -0
- data/features/license.md +9 -0
- data/features/readme.md +173 -0
- data/features/safe_stubbing/argument_matchers.feature +30 -0
- data/features/safe_stubbing/readme.md +35 -0
- data/features/{safe_mocking.feature → safe_stubbing/safe_mocking.feature} +14 -0
- data/features/{safe_stubbing.feature → safe_stubbing/safe_stubbing.feature} +18 -4
- data/features/{spies.feature → safe_stubbing/spies.feature} +19 -4
- data/features/step_definitions/rspec_steps.rb +14 -5
- data/features/support/env.rb +4 -0
- data/lib/bogus.rb +2 -0
- data/lib/bogus/adds_recording.rb +11 -7
- data/lib/bogus/any_args.rb +7 -0
- data/lib/bogus/anything.rb +11 -0
- data/lib/bogus/contract_not_fulfilled.rb +17 -10
- data/lib/bogus/copies_classes.rb +2 -6
- data/lib/bogus/creates_fakes_with_stubbed_methods.rb +40 -0
- data/lib/bogus/double.rb +28 -8
- data/lib/bogus/ensures_all_interactions_satisfied.rb +36 -0
- data/lib/bogus/fake.rb +6 -0
- data/lib/bogus/fake_configuration.rb +69 -0
- data/lib/bogus/fakes_classes.rb +21 -0
- data/lib/bogus/has_overwritten_methods.rb +24 -0
- data/lib/bogus/have_received_matcher.rb +63 -0
- data/lib/bogus/injector.rb +36 -14
- data/lib/bogus/interaction.rb +33 -17
- data/lib/bogus/makes_substitute_methods.rb +15 -0
- data/lib/bogus/mocking_dsl.rb +31 -0
- data/lib/bogus/multi_stubber.rb +15 -0
- data/lib/bogus/not_all_expectations_satisfied.rb +27 -0
- data/lib/bogus/overwriten_classes.rb +15 -0
- data/lib/bogus/overwrites_classes.rb +2 -2
- data/lib/bogus/overwrites_methods.rb +42 -0
- data/lib/bogus/proxies_method_calls.rb +23 -0
- data/lib/bogus/proxy_class.rb +25 -16
- data/lib/bogus/public_methods.rb +36 -11
- data/lib/bogus/record_interactions.rb +3 -9
- data/lib/bogus/recording_proxy.rb +5 -0
- data/lib/bogus/registers_created_fakes.rb +2 -1
- data/lib/bogus/resets_overwritten_classes.rb +14 -0
- data/lib/bogus/resets_stubbed_methods.rb +12 -0
- data/lib/bogus/responds_to_everything.rb +11 -0
- data/lib/bogus/rspec.rb +7 -0
- data/lib/bogus/rspec_adapter.rb +17 -0
- data/lib/bogus/rspec_extensions.rb +8 -20
- data/lib/bogus/shadow.rb +60 -0
- data/lib/bogus/verifies_contracts.rb +5 -1
- data/lib/bogus/verifies_stub_definition.rb +5 -0
- data/lib/bogus/version.rb +1 -1
- data/lib/tracks_existence_of_test_doubles.rb +11 -0
- data/spec/bogus/adds_recording_spec.rb +46 -10
- data/spec/bogus/anything_spec.rb +13 -0
- data/spec/bogus/copies_classes_spec.rb +4 -3
- data/spec/bogus/creates_fakes_with_stubbed_methods_spec.rb +121 -0
- data/spec/bogus/double_spec.rb +63 -20
- data/spec/bogus/ensures_all_interactions_satisfied_spec.rb +43 -0
- data/spec/bogus/fake_configuration_spec.rb +99 -0
- data/spec/bogus/fakes_classes_spec.rb +46 -0
- data/spec/bogus/have_received_matcher_spec.rb +56 -0
- data/spec/bogus/interaction_spec.rb +18 -7
- data/spec/bogus/interactions_repository_spec.rb +42 -0
- data/spec/bogus/makes_substitute_methods_spec.rb +24 -0
- data/spec/bogus/mocking_dsl_spec.rb +234 -7
- data/spec/bogus/multi_stubber_spec.rb +31 -0
- data/spec/bogus/overwriten_classes_spec.rb +27 -0
- data/spec/bogus/overwrites_classes_spec.rb +2 -2
- data/spec/bogus/overwrites_methods_spec.rb +107 -0
- data/spec/bogus/proxy_class_spec.rb +6 -0
- data/spec/bogus/record_interactions_spec.rb +3 -4
- data/spec/bogus/registers_created_fakes_spec.rb +8 -0
- data/spec/bogus/resets_overwritten_classes_spec.rb +26 -0
- data/spec/bogus/resets_stubbed_methods_spec.rb +16 -0
- data/spec/bogus/shadow_spec.rb +182 -0
- data/spec/bogus/verifies_contracts_spec.rb +9 -3
- data/spec/bogus/verifies_stub_definition_spec.rb +4 -0
- data/spec/spec_helper.rb +3 -0
- data/spec/support/fake_creator_of_fakes.rb +15 -0
- data/spec/support/sample_fake.rb +13 -0
- data/spec/tracks_existence_of_test_doubles_spec.rb +26 -0
- metadata +105 -32
- data/lib/bogus/creates_anonymous_stubs.rb +0 -27
- data/lib/bogus/invocation_matcher.rb +0 -27
- data/lib/bogus/rr_proxy.rb +0 -5
- data/spec/bogus/invocation_matcher_spec.rb +0 -26
data/lib/bogus/rspec.rb
CHANGED
@@ -3,4 +3,11 @@ require 'bogus'
|
|
3
3
|
RSpec.configure do |config|
|
4
4
|
config.extend Bogus::RSpecExtensions
|
5
5
|
config.include Bogus::MockingDSL
|
6
|
+
|
7
|
+
config.mock_with Bogus::RSpecAdapter
|
8
|
+
config.backtrace_clean_patterns << Regexp.new("lib/bogus")
|
9
|
+
|
10
|
+
config.after(:suite) do
|
11
|
+
Bogus.reset!
|
12
|
+
end
|
6
13
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Bogus
|
2
|
+
module RSpecAdapter
|
3
|
+
def setup_mocks_for_rspec
|
4
|
+
# no setup needed
|
5
|
+
end
|
6
|
+
|
7
|
+
def verify_mocks_for_rspec
|
8
|
+
Bogus.ensure_all_expectations_satisfied!
|
9
|
+
end
|
10
|
+
|
11
|
+
def teardown_mocks_for_rspec
|
12
|
+
Bogus.reset_stubbed_methods
|
13
|
+
Bogus.clear_expectations
|
14
|
+
Bogus.reset_overwritten_classes
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -1,12 +1,18 @@
|
|
1
1
|
module Bogus
|
2
2
|
module RSpecExtensions
|
3
3
|
def fake(name, opts = {}, &block)
|
4
|
-
let(name) {
|
4
|
+
let(name) { fake(name, opts, &block) }
|
5
|
+
end
|
6
|
+
|
7
|
+
def fake_class(name, opts = {})
|
8
|
+
before do
|
9
|
+
fake_class(name, opts)
|
10
|
+
end
|
5
11
|
end
|
6
12
|
|
7
13
|
def verify_contract(name)
|
8
14
|
before do
|
9
|
-
Bogus.record_calls_for(name)
|
15
|
+
Bogus.record_calls_for(name, described_class)
|
10
16
|
end
|
11
17
|
|
12
18
|
RSpec.configure do |config|
|
@@ -14,23 +20,5 @@ module Bogus
|
|
14
20
|
end
|
15
21
|
end
|
16
22
|
end
|
17
|
-
|
18
|
-
module MockingDSL
|
19
|
-
def fake(*args)
|
20
|
-
Bogus.create_anonymous_stub(*args)
|
21
|
-
end
|
22
|
-
|
23
|
-
def stub(*args)
|
24
|
-
Bogus.create_stub(*args)
|
25
|
-
end
|
26
|
-
|
27
|
-
def have_received(*args)
|
28
|
-
Bogus.have_received(*args)
|
29
|
-
end
|
30
|
-
|
31
|
-
def mock(*args)
|
32
|
-
Bogus.create_mock(*args)
|
33
|
-
end
|
34
|
-
end
|
35
23
|
end
|
36
24
|
|
data/lib/bogus/shadow.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
module Bogus
|
2
|
+
class Shadow
|
3
|
+
attr_reader :calls
|
4
|
+
|
5
|
+
def initialize(&default_return_value)
|
6
|
+
@calls = []
|
7
|
+
@stubs = []
|
8
|
+
@defaults = Hash.new(default_return_value)
|
9
|
+
@required = Set.new
|
10
|
+
end
|
11
|
+
|
12
|
+
def run(method_name, *args)
|
13
|
+
interaction = Interaction.new(method_name, args)
|
14
|
+
@calls << interaction
|
15
|
+
return_value(interaction)
|
16
|
+
end
|
17
|
+
|
18
|
+
def has_received(name, args)
|
19
|
+
@calls.include?(Interaction.new(name, args))
|
20
|
+
end
|
21
|
+
|
22
|
+
def stubs(name, *args, &return_value)
|
23
|
+
interaction = Interaction.new(name, args)
|
24
|
+
add_stub(interaction, return_value)
|
25
|
+
override_default(interaction, return_value)
|
26
|
+
@required.delete(interaction)
|
27
|
+
interaction
|
28
|
+
end
|
29
|
+
|
30
|
+
def mocks(name, *args, &return_value)
|
31
|
+
interaction = stubs(name, *args, &return_value)
|
32
|
+
@required.add(interaction)
|
33
|
+
end
|
34
|
+
|
35
|
+
def unsatisfied_interactions
|
36
|
+
@required.to_a - @calls
|
37
|
+
end
|
38
|
+
|
39
|
+
def self.has_shadow?(object)
|
40
|
+
object.respond_to?(:__shadow__)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def override_default(interaction, return_value)
|
46
|
+
return unless interaction.any_args?
|
47
|
+
@defaults[interaction.method] = return_value || proc{nil}
|
48
|
+
end
|
49
|
+
|
50
|
+
def add_stub(interaction, return_value_block)
|
51
|
+
@stubs << [interaction, return_value_block] if return_value_block
|
52
|
+
end
|
53
|
+
|
54
|
+
def return_value(interaction)
|
55
|
+
_, return_value = @stubs.reverse.find{|i, v| i == interaction}
|
56
|
+
return_value ||= @defaults[interaction.method]
|
57
|
+
return_value.call
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -7,6 +7,10 @@ class Bogus::VerifiesContracts
|
|
7
7
|
missed = doubled_interactions.for_fake(fake_name).reject do |interaction|
|
8
8
|
real_interactions.recorded?(fake_name, interaction)
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
|
+
unless missed.empty?
|
12
|
+
actual = real_interactions.for_fake(fake_name)
|
13
|
+
raise Bogus::ContractNotFulfilled.new(fake_name, missed: missed, actual: actual)
|
14
|
+
end
|
11
15
|
end
|
12
16
|
end
|
@@ -6,6 +6,7 @@ class Bogus::VerifiesStubDefinition
|
|
6
6
|
def verify!(object, method_name, args)
|
7
7
|
stubbing_non_existent_method!(object, method_name) unless object.respond_to?(method_name)
|
8
8
|
return unless object.methods.include?(method_name)
|
9
|
+
return if any_args?(args)
|
9
10
|
method = object.method(method_name)
|
10
11
|
wrong_number_of_arguments!(method, args) if under_number_of_required_arguments?(method, args.size)
|
11
12
|
wrong_number_of_arguments!(method, args) if over_number_of_allowed_arguments?(method, args.size)
|
@@ -35,4 +36,8 @@ class Bogus::VerifiesStubDefinition
|
|
35
36
|
|
36
37
|
args_count > number_of_arguments
|
37
38
|
end
|
39
|
+
|
40
|
+
def any_args?(args)
|
41
|
+
[Bogus::AnyArgs] == args
|
42
|
+
end
|
38
43
|
end
|
data/lib/bogus/version.rb
CHANGED
@@ -4,30 +4,66 @@ describe Bogus::AddsRecording do
|
|
4
4
|
module SampleModule
|
5
5
|
class Library
|
6
6
|
end
|
7
|
+
|
8
|
+
class OtherClass
|
9
|
+
end
|
7
10
|
end
|
8
11
|
|
9
12
|
let(:converts_name_to_class) { stub }
|
10
13
|
let(:create_proxy_class) { stub }
|
11
14
|
let(:overwrites_classes) { stub }
|
12
|
-
let(:
|
15
|
+
let(:overwritten_classes) { stub }
|
16
|
+
|
17
|
+
let(:adds_recording) { isolate(Bogus::AddsRecording) }
|
13
18
|
|
14
19
|
before do
|
15
20
|
stub(converts_name_to_class).convert { SampleModule::Library }
|
16
21
|
stub(create_proxy_class).call { Object }
|
17
22
|
stub(overwrites_classes).overwrite
|
18
|
-
|
19
|
-
adds_recording.add(:library)
|
23
|
+
stub(overwritten_classes).add
|
20
24
|
end
|
21
25
|
|
22
|
-
|
23
|
-
|
24
|
-
|
26
|
+
context "without class argument" do
|
27
|
+
before do
|
28
|
+
adds_recording.add(:library)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "converts the fake name to class" do
|
32
|
+
converts_name_to_class.should have_received.convert(:library)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "creates the proxy" do
|
36
|
+
create_proxy_class.should have_received.call(:library, SampleModule::Library)
|
37
|
+
end
|
38
|
+
|
39
|
+
it "swaps the classes" do
|
40
|
+
overwrites_classes.should have_received.overwrite('SampleModule::Library', Object)
|
41
|
+
end
|
25
42
|
|
26
|
-
|
27
|
-
|
43
|
+
it "records the overwritten class, so that it can be later restored" do
|
44
|
+
overwritten_classes.should have_received.add("SampleModule::Library", SampleModule::Library)
|
45
|
+
end
|
28
46
|
end
|
29
47
|
|
30
|
-
|
31
|
-
|
48
|
+
context "with class argument" do
|
49
|
+
before do
|
50
|
+
adds_recording.add(:library, SampleModule::OtherClass)
|
51
|
+
end
|
52
|
+
|
53
|
+
it "uses the passed class" do
|
54
|
+
converts_name_to_class.should_not have_received.convert(:library)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "creates the proxy" do
|
58
|
+
create_proxy_class.should have_received.call(:library, SampleModule::OtherClass)
|
59
|
+
end
|
60
|
+
|
61
|
+
it "swaps the classes" do
|
62
|
+
overwrites_classes.should have_received.overwrite('SampleModule::OtherClass', Object)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "records the overwritten class, so that it can be later restored" do
|
66
|
+
overwritten_classes.should have_received.add("SampleModule::OtherClass", SampleModule::OtherClass)
|
67
|
+
end
|
32
68
|
end
|
33
69
|
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Bogus::Anything do
|
4
|
+
it "is equal to everything" do
|
5
|
+
anything = Bogus::Anything
|
6
|
+
|
7
|
+
anything.should == "foo"
|
8
|
+
anything.should == "bar"
|
9
|
+
anything.should == 1
|
10
|
+
anything.should == Object.new
|
11
|
+
anything.should == anything
|
12
|
+
end
|
13
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Bogus::CopiesClasses do
|
4
4
|
module SampleMethods
|
@@ -57,8 +57,9 @@ describe Bogus::CopiesClasses do
|
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
60
|
-
let(:method_stringifier) { Bogus::MethodStringifier
|
61
|
-
let(:
|
60
|
+
let(:method_stringifier) { isolate(Bogus::MethodStringifier) }
|
61
|
+
let(:makes_substitute_methods) { isolate(Bogus::MakesSubstituteMethods) }
|
62
|
+
let(:copies_classes) { isolate(Bogus::CopiesClasses) }
|
62
63
|
let(:fake_class) { copies_classes.copy(klass) }
|
63
64
|
let(:fake) { fake_class.new }
|
64
65
|
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Bogus
|
4
|
+
describe CreatesFakesWithStubbedMethods do
|
5
|
+
let(:creates_fakes) { FakeCreatorOfFakes.new }
|
6
|
+
let(:fake_configuration) { stub }
|
7
|
+
let(:responds_to_everything) { stub }
|
8
|
+
let(:multi_stubber) { stub(stub_all: :stubbed_object) }
|
9
|
+
|
10
|
+
let(:creates_anonymous_stubs) { isolate(CreatesFakesWithStubbedMethods) }
|
11
|
+
|
12
|
+
before do
|
13
|
+
stub(fake_configuration).include? { false }
|
14
|
+
end
|
15
|
+
|
16
|
+
context "given symbol as first parameter" do
|
17
|
+
let(:fake) { [:foo, {as: :class}, "something"] }
|
18
|
+
|
19
|
+
before do
|
20
|
+
creates_anonymous_stubs.create(:foo, bar: 1, as: :class) { "something" }
|
21
|
+
end
|
22
|
+
|
23
|
+
it "creates fakes" do
|
24
|
+
creates_fakes.should have_created(:foo, {as: :class}, "something")
|
25
|
+
end
|
26
|
+
|
27
|
+
it "stubs all the given methods" do
|
28
|
+
multi_stubber.should have_received.stub_all(fake, bar: 1)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "given hash as first parameter" do
|
33
|
+
before do
|
34
|
+
creates_anonymous_stubs.create(bar: 1)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "does not create fakes" do
|
38
|
+
creates_fakes.fakes.should == []
|
39
|
+
end
|
40
|
+
|
41
|
+
it "stubs all the given methods" do
|
42
|
+
multi_stubber.should have_received.stub_all(responds_to_everything, bar: 1)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
context "given symbol as only parameter" do
|
47
|
+
let(:fake) { [:foo, {}, "something"] }
|
48
|
+
|
49
|
+
before do
|
50
|
+
creates_anonymous_stubs.create(:foo) { "something" }
|
51
|
+
end
|
52
|
+
|
53
|
+
it "creates fakes" do
|
54
|
+
creates_fakes.should have_created(:foo, {}, "something")
|
55
|
+
end
|
56
|
+
|
57
|
+
it "stubs all the given methods" do
|
58
|
+
multi_stubber.should have_received.stub_all(fake)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
context "with no parameters" do
|
63
|
+
before do
|
64
|
+
creates_anonymous_stubs.create
|
65
|
+
end
|
66
|
+
|
67
|
+
it "does not create fakes" do
|
68
|
+
creates_fakes.fakes.should == []
|
69
|
+
end
|
70
|
+
|
71
|
+
it "stubs all the given methods" do
|
72
|
+
multi_stubber.should have_received.stub_all(responds_to_everything)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context "when the fake was globally configured" do
|
77
|
+
let(:fake) { [:foo, {as: :class}, "SomeClass"] }
|
78
|
+
|
79
|
+
before do
|
80
|
+
stub(fake_configuration).include?(:foo) { true }
|
81
|
+
stub(fake_configuration).get(:foo) { FakeDefinition.new(opts: {as: :class},
|
82
|
+
stubs: {xyz: "abc"},
|
83
|
+
class_block: proc{"SomeClass"}) }
|
84
|
+
|
85
|
+
creates_anonymous_stubs.create(:foo)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "uses the configuration to create fake" do
|
89
|
+
creates_fakes.fakes.should == [fake]
|
90
|
+
|
91
|
+
fake_configuration.should have_received.include?(:foo)
|
92
|
+
fake_configuration.should have_received.get(:foo)
|
93
|
+
end
|
94
|
+
|
95
|
+
it "stubs the methods defined in configuration" do
|
96
|
+
multi_stubber.should have_received.stub_all(fake, xyz: "abc")
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context "overriding the global configuration" do
|
101
|
+
let(:fake) { [:foo, {as: :instance}, "SomeOtherClass"] }
|
102
|
+
|
103
|
+
before do
|
104
|
+
stub(fake_configuration).include?(:foo) { true }
|
105
|
+
stub(fake_configuration).get(:foo) { FakeDefinition.new(opts: {as: :class},
|
106
|
+
stubs: {a: "b", b: "c"},
|
107
|
+
class_block: proc{"SomeClass"}) }
|
108
|
+
|
109
|
+
creates_anonymous_stubs.create(:foo, as: :instance, b: "d", c: "e") { "SomeOtherClass" }
|
110
|
+
end
|
111
|
+
|
112
|
+
it "overrides the class block and fake options" do
|
113
|
+
creates_fakes.should have_created(:foo, {as: :instance}, "SomeOtherClass")
|
114
|
+
end
|
115
|
+
|
116
|
+
it "overrides the stubbed methods" do
|
117
|
+
multi_stubber.should have_received.stub_all(fake, a: "b", b: "d", c: "e")
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
data/spec/bogus/double_spec.rb
CHANGED
@@ -1,31 +1,74 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
module Bogus
|
4
|
+
describe Double do
|
5
|
+
shared_examples_for "double behavior" do
|
6
|
+
it "tracks existence of test doubles" do
|
7
|
+
mock(double_tracker).track(object)
|
7
8
|
|
8
|
-
|
9
|
+
double.stub.foo("a", "b") { "the result" }
|
10
|
+
end
|
9
11
|
|
10
|
-
|
12
|
+
it "verifies stub definition" do
|
13
|
+
mock(verifies_stub_definition).verify!(object, :foo, ["a", "b"])
|
11
14
|
|
12
|
-
|
13
|
-
|
14
|
-
stub(records_double_interactions).record
|
15
|
-
stub(rr_double).method_name
|
15
|
+
double.stub.foo("a", "b") { "the result" }
|
16
|
+
end
|
16
17
|
|
17
|
-
|
18
|
-
|
18
|
+
it "stubs shadow methods" do
|
19
|
+
object.extend RecordInteractions
|
20
|
+
mock(object.__shadow__).stubs(:foo, "a", "b")
|
19
21
|
|
20
|
-
|
21
|
-
|
22
|
-
end
|
22
|
+
double.stub.foo("a", "b") { "the result" }
|
23
|
+
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
25
|
+
it "mocks shadow methods" do
|
26
|
+
object.extend RecordInteractions
|
27
|
+
mock(object.__shadow__).mocks(:foo, "a", "b")
|
28
|
+
|
29
|
+
double.mock.foo("a", "b") { "the result" }
|
30
|
+
end
|
31
|
+
|
32
|
+
it "adds method overwriting" do
|
33
|
+
double.stub.foo("a", "b") { "the result" }
|
34
|
+
|
35
|
+
overwrites_methods.overwrites.should == [[object, :foo]]
|
36
|
+
end
|
37
|
+
|
38
|
+
it "records double interactions" do
|
39
|
+
mock(records_double_interactions).record(object, :foo, ["a", "b"])
|
40
|
+
|
41
|
+
double.stub.foo("a", "b") { "the result" }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
let(:double_tracker) { stub(track: nil) }
|
46
|
+
let(:verifies_stub_definition) { stub(verify!: nil) }
|
47
|
+
let(:records_double_interactions) { stub(record: nil) }
|
48
|
+
let(:overwrites_methods) { FakeMethodOverwriter.new }
|
49
|
+
let(:double) { isolate(Double) }
|
50
|
+
|
51
|
+
context "with regular objects" do
|
52
|
+
let(:object) { Samples::Foo.new }
|
53
|
+
|
54
|
+
include_examples "double behavior"
|
55
|
+
end
|
56
|
+
|
57
|
+
context "with fakes" do
|
58
|
+
let(:object) { Samples::FooFake.new }
|
59
|
+
|
60
|
+
include_examples "double behavior"
|
61
|
+
end
|
62
|
+
|
63
|
+
class FakeMethodOverwriter
|
64
|
+
def overwrite(object, method)
|
65
|
+
overwrites << [object, method]
|
66
|
+
object.extend RecordInteractions
|
67
|
+
end
|
27
68
|
|
28
|
-
|
29
|
-
|
69
|
+
def overwrites
|
70
|
+
@overwrites ||= []
|
71
|
+
end
|
72
|
+
end
|
30
73
|
end
|
31
74
|
end
|