據我所知,在單元測試methods should be isolated from their dependencies,以便他們不會受到環境變化的影響。單元測試隔離:1行代碼的20行測試?
儘管如此,將所有依賴關係排除在外讓我覺得我正在測試實現而不是行爲。
換句話說,通過隔離依賴關係,我將我的測試與實現細節相結合。因此,即使行爲(期望的結果)沒有改變,任何code refactoring都會導致測試失敗。
例如,這是一個簡單的(紅寶石)方法:
def send_request
update_attributes(response.page_params) if active?
end
這些是我的兩個對的這一行代碼分離的測試:
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()之外的任何其他方法將更改保存到dat凌辱,我的測試會失敗,即使如預期
- 如果response.page_params變更的實現,我的軟件會在生產中出現故障,數據將被保存,但測試仍然會通過
我必須做錯事。
編寫單元測試的正確方法是什麼?
我感覺你。不幸的是,沒有「編寫單元測試的正確方法」,就像沒有「銀彈」一樣。一般來說,不錯,根據經驗,與代碼本身相比,您應該花費2倍到3倍的精力編寫適當的單元測試,以達到良好的覆蓋率和信心。另一方面,我用代碼(和測試)的'右手規則'一直是,「我用更少的努力完成更多事情了嗎?」如果不是的話,那麼在某個地方需要解決一個低效率的問題。 –