简化rspec单元测试

时间:2014-07-27 20:07:39

标签: ruby unit-testing rspec

在rspec的单元测试中,很多时候必须同时指定上下文和let,这有点麻烦,似乎没必要。例如:

context 'type = :invalid' do
  let(:type) { :invalid }

  it { expect { subject }.to raise_error(ArgumentError) }
end

如果我可以做类似的事情,那将会更好(总计在很多测试中):

let_context type: :invalid do
  it { expect { subject }.to raise_error(ArgumentError) }
end

该方法将为我定义一个上下文和let(s),并且上下文的参数将类似type = :invalidlet(:type) { :invalid },因为我没有其他任何内容另外说这个变量已经改变的事实。

2 个答案:

答案 0 :(得分:1)

  
    

在rspec的单元测试中,很多时候必须同时指定上下文和let,这有点麻烦

  

听起来您可能想要使用RSpec shared context

<强>更新

RSpec为您提供的语法提供了一个DSL:a shared example。例如:

RSpec.shared_examples "some thang" do |type|
 it { expect { subject }.to raise_error(ArgumentError) }
end

RSpec.shared_examples "a thang" do
  include_examples "some thang", :invalid
  # Or whatever is more appropriate for your domain
  # I.e., If you're testing subclass behavior use it_should_behave_like()
end

答案 1 :(得分:0)

实际上,您可以通过遵循一些http://betterspecs.org建议获得更少的线路:

context 'type = :invalid' do
  let(:type) { :invalid }
  it { expect{ subject }.to raise_error(ArgumentError)
end

您的变体可以理解为

  

它会引发一个错误,预计会引发错误

虽然这更清洁

  

它希望受制于raise_error

尽管如此,它还是非常偏离主题:)

<强> UPD

喔。真的你不能把两个块传递给方法,所以下面的例子是无效的Ruby:)

context(:type) { :invalid } do
  it{ expect{ subject }.to raise_error(ArgumentError)
end

虽然你的例子

let_context type: :invalid do
  ...
end

不会像let那样执行延迟执行