require 'mini/spec' Mini::Test.autorun class Stack def empty? true end end describe Stack do before do @stack = Stack.new end it 'should be empty' do @stack.empty?.must_equal true end end
これ動きません。
何がおかしいか分かりますか?
とりあえずエラーメッセージを見てみましょう。
/opt/local/lib/ruby/site_ruby/1.8/mini/spec.rb:53: warning: already initialized constant Stack Loaded suite test Started E Finished in 0.001480 seconds. 1) Error: test_should_be_empty(Stack): ArgumentError: wrong number of arguments (0 for 1) test.rb:13:in `initialize' test.rb:13:in `new' test.rb:13:in `setup' /opt/local/lib/ruby/site_ruby/1.8/mini/test.rb:381:in `run' /opt/local/lib/ruby/site_ruby/1.8/mini/test.rb:363:in `run_test_suites' /opt/local/lib/ruby/site_ruby/1.8/mini/test.rb:358:in `each' /opt/local/lib/ruby/site_ruby/1.8/mini/test.rb:358:in `run_test_suites' /opt/local/lib/ruby/site_ruby/1.8/mini/test.rb:357:in `each' /opt/local/lib/ruby/site_ruby/1.8/mini/test.rb:357:in `run_test_suites' /opt/local/lib/ruby/site_ruby/1.8/mini/test.rb:337:in `run' /opt/local/lib/ruby/site_ruby/1.8/mini/test.rb:289:in `autorun' test.rb:11 1 tests, 0 assertions, 0 failures, 1 errors
これで分かったでしょうか?
僕はわかりませんでした。
実は犯人はdescribeで、Stackという定数を引数に与えていますが、これを内部で
module Kernel def describe desc, &block cls = Class.new(Mini::Spec) Object.const_set desc.to_s.split(/\W+/).map { |s| s.capitalize }.join, cls cls.class_eval(&block) end end
という風に、Mini::Specの子クラスにしてしまっている(あってる?)ので、beforeの中ではMini::Spec::Stack.newを呼んでいることになって、上で定義したStackにはinitializeが無いので、superclassであるSpecのinitializeを見に行って、引数が足りないことになるのでエラーになってしまっています。
これは結構致命的なのではないでしょうか?
そもそも以下のコードが動きません。
require 'mini/spec' Mini::Test.autorun describe Array do it 'I wanna make array....' do Array.new end end