More mock tests

This commit is contained in:
Michael Miller 2022-06-01 17:56:09 -06:00
parent 934c92aed1
commit 225553127d
No known key found for this signature in database
GPG Key ID: 32B47AE8F388A1FF
1 changed files with 139 additions and 31 deletions

View File

@ -21,51 +21,159 @@ Spectator.describe "Mock DSL", :smoke do
end
def method4 : Symbol
@_spectator_calls << :method4
yield
end
def method5
@_spectator_calls << :method5
yield.to_i
end
def method6
@_spectator_calls << :method6
yield
end
def method7(arg, *args, kwarg, **kwargs)
@_spectator_calls << :method7
{arg, args, kwarg, kwargs}
end
def method8(arg, *args, kwarg, **kwargs)
@_spectator_calls << :method8
yield
{arg, args, kwarg, kwargs}
end
end
context "specifying methods as keyword args" do
mock(ConcreteClass, method1: "stubbed", method2: :stubbed, method4: :block)
subject(fake) { mock(ConcreteClass) }
it "defines a mock with methods" do
aggregate_failures do
expect(fake.method1).to eq("stubbed")
expect(fake.method2).to eq(:stubbed)
end
# method1 stubbed via mock block
# method2 stubbed via keyword args
# method3 not stubbed (calls original)
# method4 stubbed via mock block (yields)
# method5 stubbed via keyword args (yields)
# method6 not stubbed (calls original and yields)
# method7 not stubbed (calls original) testing args
# method8 not stubbed (calls original and yields) testing args
mock(ConcreteClass, method2: :stubbed, method5: 42) do
stub def method1
"stubbed"
end
it "defines a subclass" do
expect(fake).to be_a(ConcreteClass)
stub def method4 : Symbol
yield
:block
end
end
it "compiles types without unions" do
aggregate_failures do
expect(fake.method1).to compile_as(String)
expect(fake.method2).to compile_as(Symbol)
end
end
subject(fake) { mock(ConcreteClass) }
def restricted(thing : ConcreteClass)
thing.method1
end
it "defines a subclass" do
expect(fake).to be_a(ConcreteClass)
end
it "can be used in type restricted methods" do
expect(restricted(fake)).to eq("stubbed")
end
it "defines stubs in the block" do
expect(fake.method1).to eq("stubbed")
end
it "does not call the original method when stubbed" do
fake.method1
fake.method2
fake.method3("foo")
expect(fake._spectator_calls).to contain_exactly(:method3)
end
it "can stub methods defined in the block" do
stub = Spectator::ValueStub.new(:method1, "override")
expect { fake._spectator_define_stub(stub) }.to change { fake.method1 }.from("stubbed").to("override")
end
it "works with blocks" do
expect(fake.method4 { :wrong }).to eq(:block)
it "defines stubs from keyword arguments" do
expect(fake.method2).to eq(:stubbed)
end
it "can stub methods from keyword arguments" do
stub = Spectator::ValueStub.new(:method2, :override)
expect { fake._spectator_define_stub(stub) }.to change { fake.method2 }.from(:stubbed).to(:override)
end
it "calls the original implementation for methods not provided a stub" do
expect(fake.method3(:xyz)).to eq(:xyz)
end
it "can stub methods after declaration" do
stub = Spectator::ValueStub.new(:method3, :abc)
expect { fake._spectator_define_stub(stub) }.to change { fake.method3(:xyz) }.from(:xyz).to(:abc)
end
it "defines stubs with yield in the block" do
expect(fake.method4 { :wrong }).to eq(:block)
end
it "can stub methods with yield in the block" do
stub = Spectator::ValueStub.new(:method4, :override)
expect { fake._spectator_define_stub(stub) }.to change { fake.method4 { :wrong } }.from(:block).to(:override)
end
it "defines stubs with yield from keyword arguments" do
expect(fake.method5 { :wrong }).to eq(42)
end
it "can stub methods with yield from keyword arguments" do
stub = Spectator::ValueStub.new(:method5, 123)
expect { fake._spectator_define_stub(stub) }.to change { fake.method5 { "0" } }.from(42).to(123)
end
it "can stub yielding methods after declaration" do
stub = Spectator::ValueStub.new(:method6, :abc)
expect { fake._spectator_define_stub(stub) }.to change { fake.method6 { :xyz } }.from(:xyz).to(:abc)
end
it "handles arguments correctly" do
args1 = fake.method7(1, 2, 3, kwarg: 4, x: 5, y: 6, z: 7)
args2 = fake.method8(1, 2, 3, kwarg: 4, x: 5, y: 6, z: 7) { :block }
aggregate_failures do
expect(args1).to eq({1, {2, 3}, 4, {x: 5, y: 6, z: 7}})
expect(args2).to eq({1, {2, 3}, 4, {x: 5, y: 6, z: 7}})
end
end
xit "handles arguments correctly with stubs", pending: "Need ProcStub" do
stub1 = Spectator::ProcStub.new(:method7) { |args| args }
stub2 = Spectator::ProcStub.new(:method8) { |args| args }
fake._spectator_define_stub(stub1)
fake._spectator_define_stub(stub2)
args1 = fake.method7(1, 2, 3, kwarg: 4, x: 5, y: 6, z: 7)
args2 = fake.method8(1, 2, 3, kwarg: 4, x: 5, y: 6, z: 7) { :block }
aggregate_failures do
expect(args1).to eq({1, {2, 3}, 4, {x: 5, y: 6, z: 7}})
expect(args2).to eq({1, {2, 3}, 4, {x: 5, y: 6, z: 7}})
end
end
it "compiles types without unions" do
aggregate_failures do
expect(fake.method1).to compile_as(String)
expect(fake.method2).to compile_as(Symbol)
expect(fake.method3(42)).to compile_as(Int32)
expect(fake.method4 { :foo }).to compile_as(Symbol)
expect(fake.method5 { "123" }).to compile_as(Int32)
expect(fake.method6 { "123" }).to compile_as(String)
end
end
def restricted(thing : ConcreteClass)
thing.method1
end
it "can be used in type restricted methods" do
expect(restricted(fake)).to eq("stubbed")
end
it "does not call the original method when stubbed" do
fake.method1
fake.method2
fake.method3("foo")
fake.method4 { :foo }
fake.method5 { "42" }
fake.method6 { 42 }
fake.method7(1, 2, 3, kwarg: 4, x: 5, y: 6, z: 7)
fake.method8(1, 2, 3, kwarg: 4, x: 5, y: 6, z: 7) { :block }
expect(fake._spectator_calls).to contain_exactly(:method3, :method6, :method7, :method8)
end
end
context "with an abstract class" do