避免过多 rspec 嵌套 subject、let 和替代参数
Avoid excessive rspec nesting with subject, let, and alternative arguments
我正在尝试进行一些 model_spec 测试,但由于不必进一步嵌套我的 rspec 代码而遇到麻烦。如果在这种情况下,我可以只拥有一组 "it's" 而不是每次我想切换变量 var 时都必须添加上下文,那就太好了。下面是代码:
describe "#some_method" do
subject { course.some_method(var) }
context 'given a project' do
let(:var) {random[1]}
it 'returns the one after' do
is_expected.to eq(random[2])
end
context 'being the last' do
let(:vars) {random.last}
it 'returns nil' do
is_expected.to be_nil
end
end
context '...you get the point, being something else' do
let(:vars) { something.else }
it 'returns nil' do
is_expected.to.to be_nil
end
end
end
end
也许我只是陷入了错误的思维模式,有人可以为我想出更好的方法吗?我被建议我绝对必须由我工作的人使用这个主题。
起初,我不同意并认为它有点累,但后来我觉得保持主题并让 let(:var) 应用于它非常有用...
你这样写怎么样?
expect(subject.call(foo))
不是很漂亮,但它摆脱了嵌套。
describe "#some_method" do
subject { course.method(:some_method) }
it 'returns the one after if given a project' do
expect(subject.call(random[1])).to eq(random[2])
end
it 'returns nil when it is the last' do
expect(subject.call(random.last)).to be_nil
end
it 'returns nil...' do
expect(subject.call(something.else)).to be_nil
end
end
RSpecs 主题是一个可以用来使测试更简洁的工具。在很多情况下使用主题是有意义的:
RSpec.describe User do
# with the help of shoulda-matchers
it { should validate_uniqueness_of :username } # implicit subject
end
RSpec.describe UsersController do
describe '#show' do
it 'is successful' do
get :show
expect(response).to have_http_status :success
end
it 'renders template show' do
get :show
expect(response).to render_template :show
end
end
#vs
describe '#show' do
subject { response }
before { get :show }
it { should have_http_status :success }
it { should render_template :success }
end
end
在某些情况下,使用 subject 会损害测试的可读性和敏锐度。
你的大学坚持你总是使用主题是完全错误的。
一个好的规则是,如果你需要一个 it
块,那么你不应该使用主题或 is_expected
。
如果您要描述方法的调用签名,您应该在规范中以与现实生活中相同的方式调用它。
let(:decorator){ described_class.new(user) }
describe "#link" do
it 'takes a class option' do
expect(decorator.link(class: 'button')).to match /class=\"button/
end
end
我会推荐 运行 rspec 和 --format documentation
选项,并检查输出是否真的有意义。一旦您获得了 100 多个规范,这可能会非常重要,因为很难记住规范实际涵盖的行为。
我正在尝试进行一些 model_spec 测试,但由于不必进一步嵌套我的 rspec 代码而遇到麻烦。如果在这种情况下,我可以只拥有一组 "it's" 而不是每次我想切换变量 var 时都必须添加上下文,那就太好了。下面是代码:
describe "#some_method" do
subject { course.some_method(var) }
context 'given a project' do
let(:var) {random[1]}
it 'returns the one after' do
is_expected.to eq(random[2])
end
context 'being the last' do
let(:vars) {random.last}
it 'returns nil' do
is_expected.to be_nil
end
end
context '...you get the point, being something else' do
let(:vars) { something.else }
it 'returns nil' do
is_expected.to.to be_nil
end
end
end
end
也许我只是陷入了错误的思维模式,有人可以为我想出更好的方法吗?我被建议我绝对必须由我工作的人使用这个主题。
起初,我不同意并认为它有点累,但后来我觉得保持主题并让 let(:var) 应用于它非常有用...
你这样写怎么样?
expect(subject.call(foo))
不是很漂亮,但它摆脱了嵌套。
describe "#some_method" do
subject { course.method(:some_method) }
it 'returns the one after if given a project' do
expect(subject.call(random[1])).to eq(random[2])
end
it 'returns nil when it is the last' do
expect(subject.call(random.last)).to be_nil
end
it 'returns nil...' do
expect(subject.call(something.else)).to be_nil
end
end
RSpecs 主题是一个可以用来使测试更简洁的工具。在很多情况下使用主题是有意义的:
RSpec.describe User do
# with the help of shoulda-matchers
it { should validate_uniqueness_of :username } # implicit subject
end
RSpec.describe UsersController do
describe '#show' do
it 'is successful' do
get :show
expect(response).to have_http_status :success
end
it 'renders template show' do
get :show
expect(response).to render_template :show
end
end
#vs
describe '#show' do
subject { response }
before { get :show }
it { should have_http_status :success }
it { should render_template :success }
end
end
在某些情况下,使用 subject 会损害测试的可读性和敏锐度。
你的大学坚持你总是使用主题是完全错误的。
一个好的规则是,如果你需要一个 it
块,那么你不应该使用主题或 is_expected
。
如果您要描述方法的调用签名,您应该在规范中以与现实生活中相同的方式调用它。
let(:decorator){ described_class.new(user) }
describe "#link" do
it 'takes a class option' do
expect(decorator.link(class: 'button')).to match /class=\"button/
end
end
我会推荐 运行 rspec 和 --format documentation
选项,并检查输出是否真的有意义。一旦您获得了 100 多个规范,这可能会非常重要,因为很难记住规范实际涵盖的行为。