📌
単体テストとか結合テストって結局なんなの?
Daily codingならぬDaily blogging2日目
二日目にしていきなり体調不良になり、今日はほとんどインプットできてません😇
とりあえず読みかけの単体テストの考え方/使い方で知ったことをアウトプットしてみる
単体テストって結局なんなんでしょうか
この本を読むまでは、なんとな〜く「単体テスト」っていうのは、一つのクラスとかモジュールとかメソッドに対するテストのことを指すのかなぁと思ってた。
「結合テスト」は、複数のクラスとかを組み合わせたテスト
例えばコントローラーからサービスクラスとか呼び出して〜最終的なコントローラから返るレスポンスは?みたいなやつ。
一つの振る舞いを定義したものが「単体テスト」
クラスとかそんなん関係なくて、「一つの振る舞いを定義したもの」が単体テストらしい
この考え方を古典学派っていうみたい。
逆に私みたいな考え方はロンドン学派。
ちなみにt_wadaさんとかは古典学派
二つの違い
by chatgpt
| 特徴 | 古典学派 (Classicist) | ロンドン学派 (Londonist) |
|---|---|---|
| テスト対象 | 実装全体の動作をテスト | インターフェースやユニット間の連携をテスト |
| 依存関係 | 実際の依存関係を使用 | モックやスタブを積極的に使用 |
| リファクタ | 実装変更に強い | モックの変更が必要になることがある |
| 速度 | 依存関係が多いと遅くなる | 依存関係を分離しているため高速 |
| メリット | 実際の動作に近いテストができる | ユニット間のインタラクションを細かくテスト可能 |
| デメリット | 複雑な依存関係ではテストが煩雑になる | 実装に依存するためリファクタ時に手間が増える |
テストの例
by chatgpt
こういうサービスクラスあたとして
# user_service.rb
class UserService
def initialize(user_repository)
@user_repository = user_repository
end
def find_user_name_by_id(user_id)
user = @user_repository.find_by_id(user_id)
user ? user[:name] : nil
end
end
# user_repository.rb
class UserRepository
def initialize
@users = { 1 => { id: 1, name: 'Alice' } }
end
def find_by_id(user_id)
@users[user_id]
end
end
古典学派だとこう
# user_service_test.rb
require 'minitest/autorun'
require_relative 'user_service'
require_relative 'user_repository'
class UserServiceTest < Minitest::Test
def setup
@repository = UserRepository.new
@service = UserService.new(@repository)
end
def test_find_user_name_by_id_returns_name
assert_equal 'Alice', @service.find_user_name_by_id(1)
end
def test_find_user_name_by_id_returns_nil_if_not_found
assert_nil @service.find_user_name_by_id(99)
end
end
ロンドン学派だとこう
# user_service_test.rb
require 'minitest/autorun'
require_relative 'user_service'
class UserServiceTest < Minitest::Test
def setup
@mock_repository = Minitest::Mock.new
@service = UserService.new(@mock_repository)
end
def test_find_user_name_by_id_returns_name
@mock_repository.expect(:find_by_id, { id: 1, name: 'Alice' }, [1])
assert_equal 'Alice', @service.find_user_name_by_id(1)
@mock_repository.verify
end
def test_find_user_name_by_id_returns_nil_if_not_found
@mock_repository.expect(:find_by_id, nil, [99])
assert_nil @service.find_user_name_by_id(99)
@mock_repository.verify
end
end
Discussion