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
|
require 'flexmock/rspec'
RSpec.configure do |config|
config.mock_with :flexmock
end
describe "Dog" do
class Dog
def wags(arg)
fail "SHOULD NOT BE CALLED"
end
def barks
fail "SHOULD NOT BE CALLED"
end
end
let(:dog) { flexmock(:on, Dog) }
context "single calls with arguments" do
before do
dog.wags(:tail)
end
it "accepts no with" do
expect(dog).to have_received(:wags)
end
it "accepts with restriction" do
expect(dog).to have_received(:wags).with(:tail)
end
it "accepts not methods called" do
expect(dog).to_not have_received(:bark)
end
it "rejects incorrect with restriction" do
should_fail(/^expected wag\(:foot\) to be received by <FlexMock:Dog Mock>/i) do
expect(dog).to have_received(:wag).with(:foot)
end
end
it "rejects not on correct matcher" do
should_fail(/^expected wags\(:tail\) to NOT be received by <FlexMock:Dog Mock>/i) do
expect(dog).to_not have_received(:wags).with(:tail)
end
end
end
context "multiple calls with multiple arguments" do
before do
dog.wags(:tail)
dog.wags(:tail)
dog.wags(:tail)
dog.wags(:head, :tail)
dog.barks
dog.barks
end
it "accepts wags(:tail) multiple times" do
expect(dog).to have_received(:wags).with(:tail).times(3)
end
it "rejects wags(:tail) wrong times value" do
should_fail(/^expected wags\(:tail\) to be received by <FlexMock:Dog Mock>/i) do
expect(dog).to have_received(:wags).with(:tail).times(2)
end
end
it "detects any_args" do
expect(dog).to have_received(:wags).times(4)
end
it "accepts once" do
expect(dog).to have_received(:wags).with(:head, :tail).once
end
it "rejects an incorrect once" do
should_fail(/^expected wags\(:tail\) to be received by <FlexMock:Dog Mock> once/i) do
expect(dog).to have_received(:wags).with(:tail).once
end
end
it "accepts twice" do
expect(dog).to have_received(:barks).twice
end
it "rejects an incorrect twice" do
should_fail(/^expected wags\(:tail\) to be received by <FlexMock:Dog Mock> twice/) do
expect(dog).to have_received(:wags).with(:tail).twice
end
end
it "accepts never" do
expect(dog).to have_received(:jump).never
end
it "rejects an incorrect never" do
should_fail(/^expected barks\(\) to be received by <FlexMock:Dog Mock> never/i) do
expect(dog).to have_received(:barks).with().never
end
end
it "rejects an incorrect never" do
expect(dog).to_not have_received(:jump)
end
end
context "with additional validations" do
it "accepts when correct" do
dog.wags(:tail)
expect(dog).to have_received(:wags).and { |arg| expect(arg).to eq(:tail) }
end
it "rejects when incorrect" do
dog.wags(:tail)
should_fail(/expected: :foot.*got: :tail/im) do
expect(dog).to have_received(:wags).and { |arg| expect(arg).to eq(:foot) }
end
end
it "rejects on all calls" do
dog.wags(:foot)
dog.wags(:foot)
dog.wags(:tail)
should_fail(/expected: :foot.*got: :tail/im) do
expect(dog).to have_received(:wags).and { |arg| expect(arg).to eq(:foot) }
end
end
it "runs the first additional block" do
dog.wags(:tail)
should_fail(/expected: :foot.*got: :tail/im) do
expect(dog).to have_received(:wags).and { |args|
expect(args).to eq(:foot)
}.and { |args|
expect(args).to eq(:tail)
}
end
end
it "runs the second additional block" do
dog.wags(:tail)
should_fail(/expected: :foot.*got: :tail/im) do
expect(dog).to have_received(:wags).and { |args|
expect(args).to eq(:tail)
}.and { |args|
expect(args).to eq(:foot)
}
end
end
end
context "with ordinal constraints" do
it "detects the first call" do
dog.wags(:tail)
dog.wags(:foot)
expect(dog).to have_received(:wags).and { |arg| expect(arg).to eq(:tail) }.on(1)
end
it "detects the second call" do
dog.wags(:tail)
dog.wags(:foot)
expect(dog).to have_received(:wags).and { |arg| expect(arg).to eq(:foot) }.on(2)
end
end
context "with blocks" do
before do
dog.wags { }
dog.barks
end
it "accepts wags with a block" do
expect(dog).to have_received(:wags).with_a_block
expect(dog).to have_received(:wags)
end
it "accepts barks without a block" do
expect(dog).to have_received(:barks).without_a_block
expect(dog).to have_received(:barks)
end
it "rejects wags without a block" do
should_fail(/without a block/) do
expect(dog).to have_received(:wags).without_a_block
end
end
it "rejects barks with a block" do
should_fail(/with a block/) do
expect(dog).to have_received(:barks).with_a_block
end
end
end
def should_fail(message_pattern)
failed = false
begin
yield
rescue RSpec::Expectations::ExpectationNotMetError => ex
failed = true
expect(ex.message).to match(message_pattern)
end
RSpec::Expectations.fail_with "Expected block to fail with message #{message_pattern.inspect}, no failure detected" unless failed
end
end
|