问题
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.
回答1:
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
来源:https://stackoverflow.com/questions/4530440/rails-rspec-how-to-test-initialize-method