Hatena::Groupcside

Cside::StudyMemo このページをアンテナに追加 RSSフィード

メインブログに書くまでもない自分用メモを垂れ流す。日々是勉強也。

カテゴリー

2012-12-22

[]Perlでいうところの use lib '/path/to/dir';

$LOAD_PATH.push('/path/to/dir')

2012-09-17

[][]RSpecでMock/Stub

公式Doc: https://github.com/rspec/rspec-mocks/blob/master/README.md

そもそもMockとStubは何が違うか

自分はこういう理解でいる

Mockオブジェクトに対するメソッドの呼び出し方を検証する
Stubメソッドが正しい結果を返すかどうかを検証する。テスト範囲を限定するため、オブジェクトやインスタンスのメソッドの戻り値を固定する

以下の文章が理解の役に立った

相互作用中心のテスト*1とはテスト対象のシステムと外部のコンポーネントとの間で正しいやり取りがされるかのテスト、いわばプロトコルのテストです。外部のコンポーネントは Mock により置き換えられ、システムから正しい呼び出しがなされているかを監視します。

したがって、例えばWebアプリの Controller の単体テストにおいて相互作用中心のテストが正しく行われてパスしているならば、Model が正しく実装された時に Controller が正しく動作するということが、Model が実装されなくても保障されます。

一方状態中心のテスト*2とはテスト対象のシステムが正しい結果を返すかというテストです。したがって、最終的に返ってくる結果だけが重要なのですが、その過程において外部のシステムとの統合が面倒な時に Stub を利用してテストを簡単にします。なので、 Stub は信頼できる外部のコンポーネント(例えばDBとかLDAPとか)に対して適応するといいと思います。

ricollab Web Tech Blog » Blog Archive » Mock と Stub について

スタブは主に生成したりコントロールしたりするのに手間がかかるオブジェクトをもみ消す [stub out] のに使われる。典型的なのはデータベース接続だろう。

ttp://d.hatena.ne.jp/devbankh/201002

よく見るメソッド

名前 種類
should_receiveMock指定したメソッドが呼ばれないとテストが落ちる
with Mock指定した引数でメソッドが呼ばれないとテストが落ちる
and_return Stub指定したメソッドの結果を固定する
典型的な例

インスタンスbookのメソッドtitleの戻り値を "The RSpec Book" に固定する

book.stub(:title).and_return("The RSpec Book")

インスタンスvalidatorのメソッドvalidatorが02134という引数で呼ばれないとこける

validator = double("validator")
validator.should_receive(:validate).with("02134")

あと、下の例のようなのをよくみるけど、MockとStubをごっちゃにしてメソッドチェーンするのは、MockとStubの脳内スイッチ切り替えが追いつかなくて読むの苦労する。。。

Object.should_receive(:method).and_return(value)
ちょっと凝った使い方

メソッドが呼ばれた回数を検証する

double.should_receive(:msg).once
double.should_receive(:msg).twice
double.should_receive(:msg).exactly(n).times
double.should_receive(:msg).at_least(:once)
double.should_receive(:msg).at_least(:twice)
double.should_receive(:msg).at_least(n).times
double.should_receive(:msg).at_most(:once)
double.should_receive(:msg).at_most(:twice)
double.should_receive(:msg).at_most(n).times
double.should_receive(:msg).any_number_of_times

and_returnに複数の値を渡すと

こういうことができる

die.stub(:roll).and_return(1,2,3)
die.roll # => 1
die.roll # => 2
die.roll # => 3
die.roll # => 3
die.roll # => 3

ショートカット記法 double(), stub, mock()

以下の記述は、

book.stub(:title).and_return("The RSpec Book")

このように書くことが出来る。

book.stub(:title) { "The RSpec Book" }
book.stub(:title => "The RSpec Book")

book = double("book", :title => "The RSpec Book")
book =   stub("book", :title => "The RSpec Book")
book =   mock("book", :title => "The RSpec Book")

HTTP RequestのStub

これにはwebmockっていうライブラリがよく使われてる。

これはとはえさんの記事でも紹介されてた。

Perlと比較してみて

  • PerlではStubは広まってるけどMockをするモジュールってメジャーなのが無い気がする
    • Test::Mock::Guardでメソッドの呼び出し回数を参照できる、くらいかな

参考

  • ttp://d.hatena.ne.jp/takihiro/20081023/1224762895

*1:Mock

*2:Stub

2012-09-14

[]proc.call や yield は Perlでいうと

sub foo {
    my ($arg1, $arg2, $coderef) = @_;
    $coderef->(); # <= これにあたる。
}

[]標準ライブラリの .so のCのソースを読む

標準ライブラリであるところの socket のなかでインクルードしてる socket.so のソースを参照したかったのだけど、 gem which socket.so では出て来なかった。あちこち探しまわったが以下のサイトに載ってた。標準ライブラリならこのサイト見れば良さそう。標準じゃないライブラリの .so のソースはrubygems.orgで見ればいいか。

http://apidock.com/ruby/Socket/connect_nonblock

[](あとで書く)pry

[]Rubyで perldoc -l にあたるもの

$ gem which rails

2012-09-01

[]include, extend

Rubyで自作の外部モジュールを読み込む方法 - include と extend と module_function - (゜∀゜)o彡 sasata299’s blog

include 'MyModule'MyModuleのインスタンスメソッドがincludeを呼んだクラスのインスタンスメソッドとして使える
extend 'MyModule'↑ のクラスメソッド版

↑ の記事のサンプルコードを見るのが手っ取り早い

zozom_module.rb

module Zozom
  def hello(name)
    puts "hello, #{name}"
  end
 
  def self.debug(data)
    p data
  end
end
require 'zozom_module'
 
class Hoge
  include Zozom
end
 
class Fuga
  extend Zozom
end
 
Hoge.new.hello("sasata299 - Hoge")
Fuga.hello("sasata299 - Fuga")

[]requre と autoload の違い

ttp://d.hatena.ne.jp/saronpasu/20080227/1204097516

require

require 'hoge'

hoge.rb の中身が「全部」読み込まれる

autolaod

autoload(:Hoge, 'hoge')
p Hoge

p Hoge した時点でhoge.rbが読み込まれる。遅延ロードとは違うな。予約って言葉のほうが正しそう。

ちなみにPerlのautoloadとは全く別物。