gpt4 book ai didi

ruby-on-rails - 单元测试隔离 : 20 lines of test for 1 line of code?

转载 作者:数据小太阳 更新时间:2023-10-29 07:56:41 25 4
gpt4 key购买 nike

据我了解,在单元测试中methods should be isolated from their dependencies , 这样他们就不会受到环境变化的影响。

尽管如此,删除所有依赖项让我觉得我是在测试实现而不是行为。

换句话说,通过隔离依赖关系,我将测试与实现细节相结合。因此,任何 code refactoring会导致测试失败,即使行为(期望的结果)没有改变。

例如,这是一个简单的 (Ruby) 方法:

  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() 之外的任何其他方法将更改保存到数据库中,我的测试将失败,即使数据将按预期保存
  • 如果 response.page_params 的实现发生变化,我的软件将在生产环境中失败,但测试仍会通过

我一定是做错了什么。

单元测试的正确写法是什么?

最佳答案

正如 AlistairIsrael 所说,我不认为您在这里完全偏离了目标。

您可以进行一些优化以使其更加简洁。一个好的测试应该清楚地表明您对代码的期望。

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 => page_params = mock('page_params')
)

# not needed as .should_receive creates a nil stub by default.
# 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

subject.should_not_receive(:update_attributes)
page.send_request
end
end
end

从上面的一些变化你可以看出 rspec 的双重助手非常非常强大,你可以构造复杂的对象并使用一些赋值的东西你可以访问链中最后计算的方法。

我对负面情况做了一个假设,但你应该明白了。测试 update_attributes 的方法调用可能更容易,也更清晰,因为您知道 page_params 如果处于事件状态,将永远不会被调用?不满足条件。

HTH

关于ruby-on-rails - 单元测试隔离 : 20 lines of test for 1 line of code?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13696735/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com