gpt4 book ai didi

ruby-on-rails - 简化和纠正 RSpec Controller 测试

转载 作者:行者123 更新时间:2023-12-04 05:26:47 25 4
gpt4 key购买 nike

我有一些 RSpec Controller 测试。有些有效,有些无效,我正试图弄清楚到底如何修复它们并使它们更有效率

理想情况下,我想看看我是否可以将每个规范变成以下形式

subject { ... }
it { ... }
it { ... }
it { ... }

请注意,对于我的所有 Controller 规范,我都为实际的 Controller 操作编写了宏。宏都经过测试并且都可以正常工作,并且名称使它们的作用非常明显。

我的“创建”测试:
formats ||= ["html", "js"]
formats.each do |format|
context "valid attributes" do
subject { do_post_create( :customer, valid_attributes, format ) }
its(:response_code) { should eq(302)}
it { should redirect_to admin_customer_path(Customer.find_by_id(???))}
it { expect { subject }.to change(Customer, :count).by(1) }
end

context "invalid attributes" do
subject { do_post_create( :customer, invalid_attributes, format ) }
its(:response_code) { should eq(200)}
it { should render_template :new }
it { expect { subject }.to_not change(Customer, :count).by(1) }
end
end

在该规范中,我一直试图找出某种方法从 post 语句中获取新创建对象的 ID。我试过“Customer.last”,但这似乎不起作用。有什么想法吗?

我的“更新”规范:
formats ||= ["html", "js"]
formats.each do |format|
context "valid attributes" do
let(:object) { FactoryGirl.create(:customer) }
subject { do_put_update( class_to_symbol(model), object.id, attributes, format ) }
its(:response_code) { should eq(302)}

it "does alter #{model}" do
do_put_update( class_to_symbol(model), object.id, attributes, format )
assigns(:customer).should eq(object)
flash[:notice].should =~ /Success/
object.reload
attributes.each do |key, value|
object.send(key.to_s).should eq(value)
end
end
end
context "invalid attributes" do
let(:object) { FactoryGirl.create("customer") }
let(:invalid_attributes) { {:username => "!"} }
subject { do_put_update( class_to_symbol(model), object.id, invalid_attributes, format ) }
its(:response_code) { should eq(200)}

it "does not alter #{model}" do
do_put_update( class_to_symbol(model), object.id, invalid_attributes, format )
assigns(:customer).should eq(object)
flash[:notice].should =~ /Fail/
object.reload
attributes.each do |key, value|
object.send(key.to_s).should_not eq(value)
end
end
end
end

在更新测试中,我想尝试以更简洁的方式表达第二个块,理想情况下,我可以对所有测试使用相同的“主题”语句。这可能吗?

最佳答案

我认为您过度考虑这些规范。不要试图将每个规范强制转换为预定义的格式 (subject/it/...) 编写规范以便它们清楚地记录应该发生的事情,然后尝试重构代码。

举个例子:使用隐式 subject用于 Controller 操作。 subjectits旨在与对象一起使用,而不是与方法一起使用,并且只有在以这种方式使用时才真正有意义。例如,这是有道理的:

subject { [1, 2, 3, 4] }
its(:size) { should == 4 }

在这里,正在测试的内容非常清楚:一个 4 元素数组的大小为 4。

但是,当你写:
subject { do_post_create( :customer, valid_attributes, format ) }
its(:response_code) { should eq(302)}

在不检查 do_post_create 的情况下,不太清楚您从哪里获得响应代码行动。您说宏的名称“使它们做什么变得相当明显”,但它们并没有使它们返回的内容相当明显,这是使用隐式主题的关键,因为它是成为主题的返回值.

只写:
it "responds with a 302" do
do_post_create(:customer, valid_attributes, format)
response.should eq(302)
end

我也不建议混合使用和不使用隐式主题的规范,因为这会使您实际测试的内容更加困惑。在您的无效属性中 context例如,您设置了一个主题,但是在您的第二个规范中,您实际上测试了 customer 的分配。 ( assigns(:customer).should eq(object) ),所以基本上这个主题与这个测试无关。 (但是,通过在此处设置主题然后不使用它,您实际上是在发送 PUT 请求两次(通过 do_put_update ),这必然会导致问题——同样,另一个不在 subject 块中发出请求的原因.)

我可以继续,但我想你明白了。如果您可以在不损害可读性的情况下完成规范,那么使规范简短而甜蜜是很棒的,但在这种情况下,我认为您已经过火了。

只有我的两分钱,希望它有所帮助。

附言如果上面的观点看起来有点极端,请阅读 documentation for implicit subjects ,你会看到他们实际上建议不要在面向公众的测试中使用隐式主题:

While the examples below demonstrate how subject can be used as a user-facing concept, we recommend that you reserve it for support of custom matchers and/or extension libraries that hide its use from examples.

关于ruby-on-rails - 简化和纠正 RSpec Controller 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13121205/

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