Ruby on rails 避免使用subject、let和可选参数进行过多的rspec嵌套

Ruby on rails 避免使用subject、let和可选参数进行过多的rspec嵌套,ruby-on-rails,ruby,rspec,Ruby On Rails,Ruby,Rspec,我正在尝试做一些模型规格测试,但由于不必进一步嵌套我的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

我正在尝试做一些模型规格测试,但由于不必进一步嵌套我的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
也许我只是陷入了错误的思维模式,有人能为我想出一个更好的方法吗?有人建议我绝对必须使用我工作的人的主题


起初,我不同意,认为这会有点麻烦,但后来我认为保留主题并让(: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
在某些情况下,使用主题会损害测试的可读性和准确性

你们学校坚持你们总是使用这门学科,这显然是错误的

一个好的规则是,如果您需要
it
块,那么您不应该使用subject或

如果您正在描述一个方法的调用签名,那么您应该在规范中以与在现实生活中相同的方式调用它

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

我建议使用
--format documentation
选项运行rspec,并检查输出是否有意义。一旦你得到了100个规范,这一点就变得非常重要,因为你越来越难记住规范实际上涵盖了什么行为。

也许你应该礼貌地让他接受他的教条,把它推下去。有时,主题可以用来编写更简洁的测试,但被迫总是使用它会导致尴尬的结构和无法阅读的测试。哈哈,我不知道……我试过了,但我很高兴,只要我们能让测试顺利进行。我对测试及其效果还很陌生,但似乎没有简单易行的方法。哦,我试试看,谢谢。我离开ruby已经有一段时间了,还没有充分利用它们在oop和操作方法上的灵活性。虽然它确实解决了问题,但不要这样做。对主语的显式主语调用被视为不好的实践,这使得仅仅为了教条的目的可读性很差。@maxcal谢谢,我同意,但这只是回到我的问题“我应该做什么?”即使我没有使用主语,仅仅为了改变参数而重复的代码仍然存在。如果我可以使用proc对象之类的东西,并将subject作为方法传递,那就太好了,但不幸的是,这不起作用。只是好奇,你知道网上有什么很棒的、实时的项目示例吗。我想看到的不仅仅是那些赤裸裸的普通人。我一直在找,但还没有找到。非常感谢你的帮助。我有时间的时候会好好看看的