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

View file

@ -21,51 +21,159 @@ Spectator.describe "Mock DSL", :smoke do
end end
def method4 : Symbol def method4 : Symbol
@_spectator_calls << :method4
yield yield
end 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 end
context "specifying methods as keyword args" do # method1 stubbed via mock block
mock(ConcreteClass, method1: "stubbed", method2: :stubbed, method4: :block) # method2 stubbed via keyword args
subject(fake) { mock(ConcreteClass) } # method3 not stubbed (calls original)
# method4 stubbed via mock block (yields)
it "defines a mock with methods" do # method5 stubbed via keyword args (yields)
aggregate_failures do # method6 not stubbed (calls original and yields)
expect(fake.method1).to eq("stubbed") # method7 not stubbed (calls original) testing args
expect(fake.method2).to eq(:stubbed) # method8 not stubbed (calls original and yields) testing args
end mock(ConcreteClass, method2: :stubbed, method5: 42) do
stub def method1
"stubbed"
end end
it "defines a subclass" do stub def method4 : Symbol
expect(fake).to be_a(ConcreteClass) yield
:block
end end
end
it "compiles types without unions" do subject(fake) { mock(ConcreteClass) }
aggregate_failures do
expect(fake.method1).to compile_as(String)
expect(fake.method2).to compile_as(Symbol)
end
end
def restricted(thing : ConcreteClass) it "defines a subclass" do
thing.method1 expect(fake).to be_a(ConcreteClass)
end end
it "can be used in type restricted methods" do it "defines stubs in the block" do
expect(restricted(fake)).to eq("stubbed") expect(fake.method1).to eq("stubbed")
end end
it "does not call the original method when stubbed" do it "can stub methods defined in the block" do
fake.method1 stub = Spectator::ValueStub.new(:method1, "override")
fake.method2 expect { fake._spectator_define_stub(stub) }.to change { fake.method1 }.from("stubbed").to("override")
fake.method3("foo") end
expect(fake._spectator_calls).to contain_exactly(:method3)
end
it "works with blocks" do it "defines stubs from keyword arguments" do
expect(fake.method4 { :wrong }).to eq(:block) 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
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 end
context "with an abstract class" do context "with an abstract class" do