mirror of
https://gitea.invidious.io/iv-org/shard-spectator.git
synced 2024-08-15 00:53:35 +00:00
Add specs for mocks and stubs docs
This commit is contained in:
parent
c0a32505ee
commit
9c888fef3f
2 changed files with 283 additions and 0 deletions
154
spec/docs/mocks_spec.cr
Normal file
154
spec/docs/mocks_spec.cr
Normal file
|
@ -0,0 +1,154 @@
|
|||
require "../spec_helper"
|
||||
|
||||
# https://gitlab.com/arctic-fox/spectator/-/wikis/Mocks
|
||||
Spectator.describe "Mocks Docs" do
|
||||
context "Abstract Types" do
|
||||
abstract class MyClass
|
||||
abstract def something : String
|
||||
end
|
||||
|
||||
mock MyClass
|
||||
|
||||
it "does something" do
|
||||
mock = mock(MyClass)
|
||||
allow(mock).to receive(:something).and_return("test") # Uncomment this line to fix.
|
||||
mock.something
|
||||
end
|
||||
end
|
||||
|
||||
abstract class MyClass
|
||||
abstract def answer : Int32
|
||||
abstract def answer(arg1, arg2) : Int32
|
||||
end
|
||||
|
||||
mock MyClass, answer: 5 do
|
||||
def answer(arg1, arg2) : Int32
|
||||
arg1 + arg2
|
||||
end
|
||||
end
|
||||
|
||||
let(answer) { 42 }
|
||||
|
||||
it "does something" do
|
||||
mock = mock(MyClass, answer: answer)
|
||||
expect(mock.answer).to eq(42)
|
||||
expect(mock.answer(1, 2)).to eq(3)
|
||||
end
|
||||
|
||||
context "Instance Variables and Initializers" do
|
||||
class MyClass
|
||||
def initialize(@value : Int32)
|
||||
end
|
||||
end
|
||||
|
||||
mock MyClass do
|
||||
def initialize(@value : Int32 = 0) # Note the lack of `stub` here.
|
||||
end
|
||||
end
|
||||
|
||||
it "can create a mock" do
|
||||
mock = mock(MyClass)
|
||||
expect(mock).to_not be_nil
|
||||
end
|
||||
end
|
||||
|
||||
context "Expecting Behavior" do
|
||||
abstract class Target
|
||||
abstract def call(value) : Nil
|
||||
end
|
||||
|
||||
class Emitter
|
||||
def initialize(@value : Int32)
|
||||
end
|
||||
|
||||
def emit(target : Target)
|
||||
target.call(@value)
|
||||
end
|
||||
end
|
||||
|
||||
describe Emitter do
|
||||
subject { Emitter.new(42) }
|
||||
|
||||
mock Target, call: nil
|
||||
|
||||
describe "#emit" do
|
||||
it "invokes #call on the target" do
|
||||
target = mock(Target)
|
||||
subject.emit(target)
|
||||
expect(target).to have_received(:call).with(42)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "does something" do
|
||||
mock = mock(MyClass)
|
||||
allow(mock).to receive(:answer).and_return(42) # Merge this line...
|
||||
mock.answer
|
||||
expect(mock).to have_received(:answer) # and this line.
|
||||
end
|
||||
|
||||
it "does something" do
|
||||
mock = mock(MyClass)
|
||||
expect(mock).to receive(:answer).and_return(42)
|
||||
mock.answer
|
||||
end
|
||||
end
|
||||
|
||||
context "Class Mocks" do
|
||||
class MyClass
|
||||
def self.something
|
||||
0
|
||||
end
|
||||
end
|
||||
|
||||
mock MyClass do
|
||||
# Define class methods with `self.` prefix.
|
||||
stub def self.something
|
||||
42
|
||||
end
|
||||
end
|
||||
|
||||
it "does something" do
|
||||
# Default stubs can be defined with key-value pairs (keyword arguments).
|
||||
mock = class_mock(MyClass, something: 3)
|
||||
expect(mock.something).to eq(3)
|
||||
|
||||
# Stubs can be changed with `allow`.
|
||||
allow(mock).to receive(:something).and_return(5)
|
||||
expect(mock.something).to eq(5)
|
||||
|
||||
# Even the expect-receive syntax works.
|
||||
expect(mock).to receive(:something).and_return(7)
|
||||
mock.something
|
||||
end
|
||||
end
|
||||
|
||||
context "Injecting Mocks" do
|
||||
struct MyStruct
|
||||
def something
|
||||
42
|
||||
end
|
||||
|
||||
def something_else(arg1, arg2)
|
||||
"#{arg1} #{arg2}"
|
||||
end
|
||||
end
|
||||
|
||||
inject_mock MyStruct, something: 5 do
|
||||
stub def something_else(arg1, arg2)
|
||||
"foo bar"
|
||||
end
|
||||
end
|
||||
|
||||
specify "creating a mocked type without `mock`" do
|
||||
inst = MyStruct.new
|
||||
expect(inst).to receive(:something).and_return(7)
|
||||
inst.something
|
||||
end
|
||||
|
||||
it "leaks stubs to other examples" do
|
||||
inst = mock(MyStruct)
|
||||
expect(inst.something).to eq(7) # Previous stub was leaked.
|
||||
end
|
||||
end
|
||||
end
|
129
spec/docs/stubs_spec.cr
Normal file
129
spec/docs/stubs_spec.cr
Normal file
|
@ -0,0 +1,129 @@
|
|||
require "../spec_helper"
|
||||
|
||||
Spectator.describe "Stubs Docs" do
|
||||
double :time_double, time_in: Time.utc(2016, 2, 15, 10, 20, 30)
|
||||
double :my_double, something: 42, answer?: false
|
||||
|
||||
let(dbl) { double(:my_double) }
|
||||
|
||||
def receive_time_in_utc
|
||||
receive(:time_in).with(:utc).and_return(Time.utc)
|
||||
end
|
||||
|
||||
it "returns the time in UTC" do
|
||||
dbl = double(:time_double)
|
||||
allow(dbl).to receive_time_in_utc
|
||||
expect(dbl.time_in(:utc).zone.name).to eq("UTC")
|
||||
end
|
||||
|
||||
context "Modifiers" do
|
||||
double :my_double, something: 42, answer?: false
|
||||
|
||||
let(dbl) { double(:my_double) }
|
||||
|
||||
context "and_return" do
|
||||
specify do
|
||||
allow(dbl).to receive(:something).and_return(42)
|
||||
expect(dbl.something).to eq(42)
|
||||
end
|
||||
|
||||
specify do
|
||||
allow(dbl).to receive(:something).and_return(1, 2, 3)
|
||||
expect(dbl.something).to eq(1)
|
||||
expect(dbl.something).to eq(2)
|
||||
expect(dbl.something).to eq(3)
|
||||
expect(dbl.something).to eq(3)
|
||||
end
|
||||
end
|
||||
|
||||
context "and_raise" do
|
||||
specify do
|
||||
allow(dbl).to receive(:something).and_raise # Raise `Exception` with no message.
|
||||
expect { dbl.something }.to raise_error(Exception)
|
||||
|
||||
allow(dbl).to receive(:something).and_raise(IO::Error) # Raise `IO::Error` with no message.
|
||||
expect { dbl.something }.to raise_error(IO::Error)
|
||||
|
||||
allow(dbl).to receive(:something).and_raise(KeyError, "Missing key: :foo") # Raise `KeyError` with the specified message.
|
||||
expect { dbl.something }.to raise_error(KeyError, "Missing key: :foo")
|
||||
|
||||
exception = ArgumentError.new("Malformed")
|
||||
allow(dbl).to receive(:something).and_raise(exception) # Raise `exception`.
|
||||
expect { dbl.something }.to raise_error(ArgumentError, "Malformed")
|
||||
end
|
||||
end
|
||||
|
||||
context "with" do
|
||||
specify do
|
||||
allow(dbl).to receive(:answer?).and_return(false)
|
||||
allow(dbl).to receive(:answer?).with(42).and_return(true)
|
||||
expect(dbl.answer?(42)).to be_true
|
||||
expect(dbl.answer?(5)).to be_false
|
||||
end
|
||||
|
||||
specify do
|
||||
allow(dbl).to receive(:answer?).with(Int, key: /foo/).and_return(true)
|
||||
expect(dbl.answer?(42, key: "foobar")).to be_true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "Expect-Receive Syntax" do
|
||||
class Driver
|
||||
def doit(thing)
|
||||
thing.call
|
||||
end
|
||||
end
|
||||
|
||||
describe Driver do
|
||||
describe "#doit" do
|
||||
double :thing, call: 5
|
||||
|
||||
it "calls thing.call (1)" do
|
||||
thing = double(:thing)
|
||||
allow(thing).to receive(:call).and_return(42)
|
||||
subject.doit(thing)
|
||||
expect(thing).to have_received(:call)
|
||||
end
|
||||
|
||||
it "calls thing.call (2)" do
|
||||
thing = double(:thing)
|
||||
expect(thing).to receive(:call).and_return(42)
|
||||
subject.doit(thing)
|
||||
end
|
||||
|
||||
it "calls thing.call (3)" do
|
||||
thing = double(:thing)
|
||||
allow(thing).to receive(:call).and_return(42)
|
||||
expect(thing).to_eventually have_received(:call)
|
||||
subject.doit(thing)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
specify do
|
||||
expect(dbl).to receive(:answer?).with(42).and_return(true)
|
||||
dbl.answer?(42)
|
||||
end
|
||||
end
|
||||
|
||||
context "Default Stubs" do
|
||||
double :my_double, foo: "foo" do # Default stub for #foo
|
||||
# Default stub for #bar
|
||||
stub def bar
|
||||
"bar"
|
||||
end
|
||||
end
|
||||
|
||||
it "does something" do
|
||||
dbl = double(:my_double)
|
||||
expect(dbl.foo).to eq("foo")
|
||||
expect(dbl.bar).to eq("bar")
|
||||
|
||||
# Overriding initial defaults.
|
||||
dbl = double(:my_double, foo: "FOO", bar: "BAR")
|
||||
expect(dbl.foo).to eq("FOO")
|
||||
expect(dbl.bar).to eq("BAR")
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue