1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231
|
#!/usr/bin/env ruby
#---
# Copyright 2003-2013 by Jim Weirich (jim.weirich@gmail.com).
# All rights reserved.
# Permission is granted for use, copying, modification, distribution,
# and distribution of modified versions of this work as long as the
# above copyright notice is included.
#+++
require 'test_helper'
class TestNewInstances < Minitest::Test
include FlexMock::Minitest
include FlexMock::RedirectError
class Dog
def bark
:woof
end
def wag
:tail
end
def self.make
new
end
end
class Cat
attr_reader :name
def initialize(name, &block)
@name = name
block.call(self) if block_given?
end
end
class Connection
def initialize(*args)
yield(self) if block_given?
end
def send(args)
post(args)
end
def post(args)
:unstubbed
end
end
def test_new_instances_allows_stubbing_of_existing_methods
flexstub(Dog).new_instances do |obj|
obj.should_receive(:bark).and_return(:whimper)
end
m = Dog.new
assert_equal :whimper, m.bark
end
def test_new_instances_is_transparent_after_flexmock_teardown
flexstub(Dog).new_instances.should_receive(:bark).never
flexmock_teardown
Dog.new
end
def test_new_instances_before_and_after_flexmock_teardown_are_disconnected
flexstub(Dog).new_instances.should_receive(:bark).never
flexmock_teardown
flexstub(Dog).new_instances.should_receive(:bark).once
Dog.new.bark
end
def test_new_instances_stubs_still_have_existing_methods
flexstub(Dog).new_instances do |obj|
obj.should_receive(:bark).and_return(:whimper)
end
m = Dog.new
assert_equal :tail, m.wag
end
def test_new_instances_mock_methods_called_in_initialize
klass = Class.new do
attr_reader :value
def initialize; @value = bark end
def bark; :original end
end
flexmock(klass).new_instances do |obj|
obj.should_receive(:bark).and_return(:mock)
end
obj = klass.new
assert_equal :mock, obj.value
end
def test_new_instances_will_pass_args_to_new
flexstub(Cat).new_instances do |obj|
obj.should_receive(:meow).and_return(:scratch)
end
x = :not_called
m = Cat.new("Fido") { x = :called }
assert_equal :scratch, m.meow
assert_equal "Fido", m.name
assert_equal :called, x
end
# Some versions of the software had problems invoking the block after a
# second stubbing.
def test_new_gets_block_after_restubbing
flexstub(Cat).new_instances { }
x = :not_called
m = Cat.new("Fido") { x = :called }
assert_equal :called, x
flexmock_teardown
flexstub(Cat).new_instances { }
x = :not_called
m = Cat.new("Fido") { x = :called }
assert_equal :called, x
end
def test_new_instances_stub_verification_happens_on_teardown
flexstub(Dog).new_instances do |obj|
obj.should_receive(:bark).once.and_return(nil)
end
Dog.new
ex = assert_raises(assertion_failed_error) { flexmock_teardown }
assert_match(/method 'bark\(.*\)' called incorrect number of times/i, ex.message)
end
def test_new_instances_reports_error_on_non_classes
ex = assert_raises(ArgumentError) {
flexstub(Dog.new).new_instances do |obj|
obj.should_receive(:hi)
end
}
assert_match(/Class/, ex.message)
assert_match(/new_instances/, ex.message)
end
def test_does_not_by_default_stub_objects_created_with_allocate
flexstub(Dog).new_instances do |obj|
obj.should_receive(:bark).and_return(:whimper)
end
m = Dog.allocate
assert_equal :woof, m.bark
end
def test_can_explicitly_stub_objects_created_with_allocate
flexstub(Dog).new_instances(:allocate) do |obj|
obj.should_receive(:bark).and_return(:whimper)
end
m = Dog.allocate
assert_equal :whimper, m.bark
end
def test_can_stub_objects_created_with_arbitrary_class_methods
flexstub(Dog).new_instances(:make) do |obj|
obj.should_receive(:bark).and_return(:whimper)
end
assert_equal :whimper, Dog.make.bark
end
def test_stubbing_arbitrary_class_methods_leaves_new_alone
flexstub(Dog).new_instances(:make) do |obj|
obj.should_receive(:bark).and_return(:whimper)
end
assert_equal :woof, Dog.new.bark
end
def test_stubbing_new_and_allocate_doesnt_double_stub_objects_on_new
counter = 0
flexstub(Dog).new_instances do |obj|
counter += 1
end
Dog.new
assert_equal 1, counter
end
# Current behavior does not install stubs into the block passed to new.
# This is rather difficult to achieve, although it would be nice. For the
# moment, we assure that they are not stubbed, but I am willing to change
# this in the future.
def test_blocks_on_new_do_not_have_stubs_installed
flexstub(Connection).new_instances do |new_con|
new_con.should_receive(:post).and_return {
:stubbed
}
end
block_run = false
Connection.new do |c|
assert_equal :stubbed, c.send("hi")
block_run = true
end
assert block_run
end
def test_new_instances_accept_chained_expectations
flexmock(Dog).new_instances.
should_receive(:growl).and_return(:grr).
should_receive(:roll_over).and_return(:flip)
assert_equal :grr, Dog.new.growl
assert_equal :flip, Dog.new.roll_over
end
def test_fancy_use_of_chained_should_received
flexmock(Dog).new_instances.should_receive(:woof => :grrr)
assert_equal :grrr, Dog.new.woof
end
def test_writable_accessors
flexmock(Dog).new_instances.should_receive(:name=).with("fido")
dog = Dog.new
dog.name = 'fido'
end
def test_ordering_can_be_specified
dog = Dog.new
flexmock(dog).should_receive(:bark).once.ordered
flexmock(dog).should_receive(:bite).once.ordered
dog.bark
dog.bite
end
def test_ordering_can_be_specified_in_groups
dog = Dog.new
flexmock(dog).should_receive(:wag).once.ordered(:safe)
flexmock(dog).should_receive(:bark).once.ordered(:danger)
flexmock(dog).should_receive(:bite).once.ordered(:danger)
dog.wag
dog.bite
dog.bark
end
end
|