使用控制器规格的单行语法
Using the one-liner syntax for controller specs
我正在尝试为 API 控制器编写简洁的测试,但我在使用 RSpec 提供的 "one-liner" 语法时遇到了问题。
我明确地覆盖了主题,以引用发帖的 action 而不是 controller:
let (:params) { some_valid_params_here }
subject { post :create, params }
当我使用单行语法测试 http_status 时,它工作正常:
it { is_expected.to have_http_status(:created) }
# pass!
但是当我尝试将它用于不同的期望时,它爆炸了:
it { is_expected.to change{SomeActiveRecordModel.count}.by(1) }
# fail! "expected result to have changed by 1, but was not given a block"
值得注意的是,当我 运行 以更长的形式明确调用主题时,第二个期望有效:
it "creates a model" do
expect{ subject }.to change{SomeActiveRecordModel.count}.by(1)
end
# pass
这是否只是单行语法的弱点,它无法处理这种更复杂的表达式?还是我误解了主题是如何推断到这些测试中的?
(注意:我知道将主题设置为动作有一些批评者,我很高兴听到意见,但这不是这个问题的目的)。
你可以这样做
subject { -> { post :create, params } }
接着
it { is_expected.to change(SomeActiveRecordModel, :count).by(1) }
在这里你对此进行了很好的讨论
github_topic
如前所述,有一个涉及 subject
的简单解决方案;它不需要 lambda
;我以这种方式为我的 CategoryController#show
应用它:
describe '#show' do
subject { get :show, id: category }
context "as guest" do
it { is_expected.to render_template('show') }
end
end
我正在尝试为 API 控制器编写简洁的测试,但我在使用 RSpec 提供的 "one-liner" 语法时遇到了问题。
我明确地覆盖了主题,以引用发帖的 action 而不是 controller:
let (:params) { some_valid_params_here }
subject { post :create, params }
当我使用单行语法测试 http_status 时,它工作正常:
it { is_expected.to have_http_status(:created) }
# pass!
但是当我尝试将它用于不同的期望时,它爆炸了:
it { is_expected.to change{SomeActiveRecordModel.count}.by(1) }
# fail! "expected result to have changed by 1, but was not given a block"
值得注意的是,当我 运行 以更长的形式明确调用主题时,第二个期望有效:
it "creates a model" do
expect{ subject }.to change{SomeActiveRecordModel.count}.by(1)
end
# pass
这是否只是单行语法的弱点,它无法处理这种更复杂的表达式?还是我误解了主题是如何推断到这些测试中的?
(注意:我知道将主题设置为动作有一些批评者,我很高兴听到意见,但这不是这个问题的目的)。
你可以这样做
subject { -> { post :create, params } }
接着
it { is_expected.to change(SomeActiveRecordModel, :count).by(1) }
在这里你对此进行了很好的讨论 github_topic
如前所述,有一个涉及 subject
的简单解决方案;它不需要 lambda
;我以这种方式为我的 CategoryController#show
应用它:
describe '#show' do
subject { get :show, id: category }
context "as guest" do
it { is_expected.to render_template('show') }
end
end