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
|
require 'support/doubled_classes'
module RSpec
module Mocks
RSpec.describe 'Expected argument verification (when `#with` is called)' do
# Note: these specs here aren't meant to be exhaustive. The specs in
# rspec-support for the method signature verifier are. Here we are just
# covering the code paths within the `with` implementation, including
# the special handling for `any_args` and `no_args`.
context "when doubling an unloaded class" do
it 'allows any arguments' do
expect(defined?(UnloadedClass)).to be_falsey
inst_dbl = instance_double("UnloadedClass")
expect {
expect(inst_dbl).to receive(:message).with(:foo, :bar, :bazz)
}.not_to raise_error
reset inst_dbl
end
end
context "when doubling a loaded class" do
let(:dbl) { instance_double(LoadedClass) }
after { reset dbl }
context "when `any_args` is used" do
context "as the only argument" do
it "is allowed regardless of how many args the method requires" do
expect {
expect(dbl).to receive(:instance_method_with_two_args).with(any_args)
}.not_to raise_error
end
end
context "as the first argument, with too many additional args" do
it "is disallowed" do
expect {
expect(dbl).to receive(:instance_method_with_two_args).with(any_args, 1, 2, 3)
}.to fail_with("Wrong number of arguments. Expected 2, got 3.")
end
end
context "as the first argument, with an allowed number of additional args" do
it "is allowed" do
expect {
expect(dbl).to receive(:instance_method_with_two_args).with(any_args, 1, 2)
}.not_to raise_error
expect {
expect(dbl).to receive(:instance_method_with_two_args).with(any_args, 1)
}.not_to raise_error
end
end
end
context "when `no_args` is used" do
it "allows a method expectation on a method that accepts no arguments" do
expect(LoadedClass.instance_method(:defined_instance_method).arity).to eq(0)
expect {
expect(dbl).to receive(:defined_instance_method).with(no_args)
}.not_to raise_error
end
it "allows a method expectation on a method that has defaults for all arguments" do
expect {
expect(dbl).to receive(:instance_method_with_only_defaults).with(no_args)
}.not_to raise_error
end
it "does not allow a method expectation on a method that has required arguments" do
expect {
expect(dbl).to receive(:instance_method_with_two_args).with(no_args)
}.to fail_with("Wrong number of arguments. Expected 2, got 0.")
end
if RSpec::Support::RubyFeatures.required_kw_args_supported?
context "for a method with required keyword args" do
it 'covers the required args when `any_args` is last' do
expect {
expect(dbl).to receive(:kw_args_method).with(1, any_args)
}.not_to raise_error
end
it 'does not cover the required args when there are args after `any_args`' do
expect {
# Use eval to avoid syntax error on 1.8 and 1.9
eval("expect(dbl).to receive(:kw_args_method).with(any_args, optional_arg: 3)")
}.to fail_with("Missing required keyword arguments: required_arg")
end
end
end
end
if RSpec::Support::RubyFeatures.required_kw_args_supported?
it 'does not cover required args when `any_args` is not used' do
expect {
expect(dbl).to receive(:kw_args_method).with(anything)
}.to fail_with("Missing required keyword arguments: required_arg")
end
end
context "when a list of args is provided" do
it "allows a method expectation when the arity matches" do
expect {
expect(dbl).to receive(:instance_method_with_two_args).with(1, 2)
}.not_to raise_error
end
it "does not allow a method expectation with an arity mismatch" do
expect {
expect(dbl).to receive(:instance_method_with_two_args).with(1, 2, 3)
}.to fail_with("Wrong number of arguments. Expected 2, got 3.")
end
end
context "when `with` is called with no args" do
it "fails with an error suggesting the user use `no_args` instead" do
expect {
expect(dbl).to receive(:instance_method_with_two_args).with
}.to raise_error(ArgumentError, /no_args/)
end
end
end
end
end
end
|