Chapter 17 Extending RSpec その2の続き。
17.4 Macros
下記のコードを
describe Widget do it "requires a name" do widget = Widget.new widget.valid? widget.should have(1).error_on(:name) end end
カスタムマッチャを使って極限まで省略すると下記のような感じに出来る。(shouldのレシーバを省略すると、describeのオブジェクトをnewしたものが補完される。)
describe Widget do it { should require_attribute(:name) } end
これをmacroを使うともっとよくできる。macroはrspecの代替プラグインshouldaから来ている。
describe Widget do it_validates_presence_of Widget, :name end
shared example groupに似ているけど、独自の名前をもてるところと引数を渡せるところが違う。下記のような controller の examlple があるとすると
describe ProjectsController do context "handling GET index" do it "should render the index template" do get :index controller.should render_template("index") end it "should assign @projects => Project.all" do Project.should_receive(:all).and_return(['this array']) get :index assigns[:projects].should == ['this array'] end end end
macroを使うと下記のように書けるようになる。スッキリ!
describe ProjectsController do get :index do should_render "index" should_assign :projects => [Project, :all] end end
macroは下記のような感じで定義する
module ControllerMacros def should_render(template) it "should render the #{template} template" do do_request response.should render_template(template) end end def should_assign(hash) variable_name = hash.keys.first model, method = hash[variable_name] model_access_method = [model, method].join('.') it "should assign @#{variable_name} => #{model_access_method}" do expected = "the value returned by #{model_access_method}" model.should_receive(method).and_return(expected) do_request assigns[variable_name].should == expected end end def get(action) define_method :do_request do get action end yield end end Spec::Runner.configure do |config| config.use_transactional_fixtures = true config.use_instantiated_fixtures = false config.fixture_path = RAILS_ROOT + '/spec/fixtures/' config.extend(ControllerMacros, :type => :controller) end
全部のexample groupでControllerMacrosモジュールを使いたくない場合は、下記のように明示的にマクロをextendするといい。
describe ProjectsController do extend ControllerMacros # ... end
17.5 Custom Formatters
spec実行後のメッセージのフォーマットをカスタムする方法について。今のところbuilt-inで満足しているので省略。