你可以将一个块传递给 Rails RSpec 中的 it_behaves_like 吗?

huangapple go评论118阅读模式
英文:

Can I pass a block to it_behaves_like in Rails RSpec?

问题

在使用it_behaves_like时,你想要扩展预期列表是否可以传递一个块?例如,你这样写:

  1. it_behaves_like "success" do
  2. expect(response['id']).to eq(1)
  3. end

希望RSpec将其编译成这样:

  1. it "returns data" do
  2. post "/api/users", params: params
  3. expect(response.status).to eq(201)
  4. expect(response['id']).to eq(1)
  5. end

上述代码显然不按预期工作,但我想知道如何编写它,以便RSpec能够理解并按照我上面期望的结果进行编译。这种情况是否可行?

不幸的是,RSpec不会按你期望的方式处理它。it_behaves_like并不支持在块内添加额外的期望。你需要在shared_examples中定义完整的示例,而不能在调用it_behaves_like时添加额外的期望。

要实现你的期望结果,你可以将额外的期望添加到shared_examples中,如下所示:

  1. shared_examples 'success' do
  2. let(:params) { key: 'value' }
  3. it 'returns data' do
  4. post '/api/users', params: params
  5. expect(response.status).to eq(201)
  6. expect(response['id']).to eq(1)
  7. end
  8. end

然后,你可以使用it_behaves_like调用它:

  1. it_behaves_like 'success'

这将在测试中包括所有你想要的期望。

英文:

Providing that I have a shared example:

  1. shared_examples 'success' do
  2. let(:params) { key: "value" }
  3. it "returns data" do
  4. post "/api/users", params: params
  5. expect(response.status).to eq (201)
  6. end
  7. end

When I use this shared example with it_behaves_like, can I pass a block to it to extends the list of expected?

For example, I write it like this:

  1. it_behaves_like "success" do
  2. expect(response['id]).to eq(1)
  3. end

in hope of rspec to compile it like this:

  1. it "returns data" do
  2. post "/api/users", params: params
  3. expect(response.status).to eq (201)
  4. expect(response['id]).to eq(1)
  5. end

The above code is obviously not working as I wanted, but I want to know how to write it so that RSpec can understand it like my expected outcome above. Is it possible?

答案1

得分: 1

你可以将其分成一个共享上下文,用于执行API请求,和一个共享示例,用于检查状态代码,例如:

  1. shared_context 'request' do
  2. before do
  3. post '/api/users', params: params
  4. end
  5. end
  6. shared_examples 'success' do
  7. it 'returns with 201 status code' do
  8. expect(response.status).to eq(201)
  9. end
  10. end

然后可以组合它们:

  1. describe 'a successful request' do
  2. include_context 'request' do
  3. let(:params) { { key: 'value' } }
  4. end
  5. it_behaves_like 'success'
  6. it 'returns data' do
  7. expect(response['id']).to eq(1)
  8. end
  9. end
英文:

You could separate it into a shared context which performs the API request and a shared example which checks the status code, e.g.:

  1. shared_context 'request' do
  2. before do
  3. post '/api/users', params: params
  4. end
  5. end
  6. shared_examples 'success' do
  7. it 'returns with 201 status code' do
  8. expect(response.status).to eq (201)
  9. end
  10. end

These can then be combined:

  1. describe 'a successful request' do
  2. include_context 'request' do
  3. let(:params) { { key: 'value' } }
  4. end
  5. it_behaves_like 'success'
  6. it 'returns data' do
  7. expect(response['id']).to eq(1)
  8. end
  9. end

huangapple
  • 本文由 发表于 2023年7月24日 17:33:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/76753138.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定