私が理解しているように、単体テストでは、環境の変更の影響を受けないように、メソッドを依存関係から分離する必要があります。
それでも、すべての依存関係をスタブ化すると、動作ではなく実装をテストしているように感じます。
言い換えれば、依存関係を分離することで、テストを実装の詳細に結合しています。したがって、コードのリファクタリングは、動作 (望ましい結果) が変わらなくても、テストの失敗を引き起こします。
たとえば、これは単純な (Ruby) メソッドです。
def send_request
update_attributes(response.page_params) if active?
end
そして、これらは、この 1 行のコードに対する私の 2 つの独立したテストです。
let(:page) { Page.new }
describe '#send_request' do
context 'when a page is active' do
it 'updates page with the response parameters' do
page.active = true
response = double('response')
page_params = double('page_params')
response.stub(:page_params).and_return(page_params)
page.stub(:response).and_return(response)
page.stub(:update_attributes).and_return(nil)
page.should_receive(:update_attributes).with(page_params)
page.send_request
end
end
context 'when a page is inactive' do
it 'does NOT send a request' do
page.active = false
page.should_not_receive(:response)
page.send_request
end
end
end
テストはパスしていますが、深刻な問題がいくつか見られます。
- 後で update_attributes() 以外の方法を使用して変更をデータベースに保持することにした場合、データは期待どおりに保存されますが、テストは失敗します。
- response.page_params の実装が変更された場合、ソフトウェアは本番環境で失敗しますが、テストは引き続き合格します
私は何か間違ったことをしているに違いない。
単体テストを書く正しい方法は何ですか?