An idiomatic mocking library for Crystal 💎
Meaning of Agyan.
-
Add the dependency to your
shard.yml
:development_dependencies: agyan: github: tkshnwesper/agyan
-
Run
shards install
- Create a mock class
- Instantiate the above class into an object
- Setup expectations and return values for methods on that object
- Pass that object into the code that you want to test
require "agyan"
import Agyan
mock_class
can only be called at the root level or in modules, because it is a macro that creates a mock class, and classes have a limitation that they cannot be created inside methods.
class Garden
end
mock_class(Garden) # Creates class called `MockGarden`
class Rocket
def blast_off
end
end
mock_class(Rocket, MockedRocket) # Creates class called `MockedRocket`
# `blast_off` can now be mocked on an instance of `MockedRocket`
class Vault
def open : Bool
end
end
mock_class(Vault)
describe Vault do
it "opens vault" do
mock = MockVault.new
MockVault.on(mock, :open).with.then_return(true)
mock.open.should be_truthy
end
end
class Vault
def open(pin : Int32) : Bool
end
end
mock_class(Vault)
describe Vault do
it "opens vault" do
mock = MockVault.new
MockVault.on(mock, :open).with(123).then_return(true)
mock.open(123).should be_truthy
end
end
Check whether your code is calling the mocked methods with the correct parameters.
class Vault
def open(pin : Int32) : Bool
end
end
mock_class(Vault)
describe Vault do
it "opens vault" do
mock = MockVault.new
MockVault.on(mock, :open).with(123).then_return(true)
MockVault.assert_expectations(mock) # raises exception as `open` is not called with `(123)`
end
end
class Vault
def open(pin : Int32) : Bool
end
def open(pin : String) : Bool
end
end
mock_class(Vault)
describe Vault do
it "opens vault" do
mock = MockVault.new
MockVault.on(mock, :open).with(123).then_return(true)
MockVault.on(mock, :open).with("Agyan").then_return(false)
mock.open(123).should be_truthy
mock.open("Agyan").should be_falsey
end
end
class ClassWithInitialize
def initialize(value : Int32)
end
end
mock_class(ClassWithInitialize)
describe ClassWithInitialize do
it "mocks initialize methods" do
MockClassWithInitialize.on(:initialize).with(10)
mock = MockClassWithInitialize.new(10)
MockClassWithInitialize.assert_expectations(mock)
end
end
Run tests using
crystal spec
- Fork it (https://github.com/tkshnwesper/agyan/fork)
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create a new Pull Request
- Saurabh Machave - creator and maintainer