How can I specify #initialize
behaviour with RSpec? For example here:
generator.rb
class Generator
attr_accessor :seed
def initialize(seed = nil)
@seed = seed || pick_seed
end
def pick_seed
Time.now.to_i
end
end
generator_spec.rb
require 'generator'
describe Generator
it "calls 'pick_seed' method unless seed specified" do
end
end
I'd like to set expectation that pick_seed
method called from #initialize
method.
Running tests by their file or directory names is the most familiar way to run tests with RSpec. RSpec can take a file name or directory name and run the file or the contents of the directory. So you can do: rspec spec/jobs to run the tests found in the jobs directory.
RSpec is a testing tool for Ruby, created for behavior-driven development (BDD). It is the most frequently used testing library for Ruby in production applications. Even though it has a very rich and powerful DSL (domain-specific language), at its core it is a simple tool which you can start using rather quickly.
RSpec is a unit test framework for the Ruby programming language. RSpec is different than traditional xUnit frameworks like JUnit because RSpec is a Behavior driven development tool. What this means is that, tests written in RSpec focus on the "behavior" of an application being tested.
For me, expectations are about designing conversations among collaborators. So, you have to decide - is #pick_seed
an internal implementation detail or part of a collaborating role's interface?
If pick_seed
is an implementation detail, an expectation is the wrong tool for the job. And, since you have an accessor for seed, you can proceed thusly (notice the one-assertion-per-example):
class Generator
attr_accessor :seed
def initialize(seed = nil)
@seed = seed || pick_seed
end
def pick_seed
Time.now.to_i
end
end
describe Generator do
context "creating" do
context "when a seed is specified" do
it "uses that seed" do
seed = 123
generator = Generator.new(seed)
generator.seed.should == seed
end
end
context "when a seed is not specified" do
it "creates its own seed" do
generator = Generator.new
generator.seed.should_not be_nil
end
end
end
end
OTOH, if picking the seed is part of the "seed picker" role, then mocks are valuable in designing the seed picker, and dependency injection is a standard method of assigning the roles. You could write something like:
class GeneratorWithCollaborator
attr_accessor :seed
def initialize(seed = nil, seed_picker = self)
@seed = seed || seed_picker.pick_seed
end
def pick_seed
Time.now.to_i
end
end
describe GeneratorWithCollaborator do
context "creating" do
context "when a seed is specified" do
it "uses that seed" do
seed = 123
seed_picker = double('seed picker')
seed_picker.should_not_receive(:pick_seed)
generator = GeneratorWithCollaborator.new(seed, seed_picker)
generator.pick_seed
end
end
context "when a seed is not specified" do
it "delegates to its seed picker" do
seed_picker = double('seed picker')
seed_picker.should_receive(:pick_seed)
generator = GeneratorWithCollaborator.new(nil, seed_picker)
end
end
end
end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With