如何在单个Context块中关闭已引入的RSpec Shared Context?
回答:可以实现,但需要用变通方法
RSpec本身并没有提供直接"禁用"已引入共享上下文的原生API,但我们可以通过几种方式达到类似的效果,具体取决于你的共享上下文里包含的内容:
方法1:重构代码,从结构上隔离共享上下文的作用范围
这是最干净、推荐优先使用的方案——把需要依赖共享上下文的测试代码单独放在一个子context里,而不需要的部分放在外面,这样自然就不会继承共享上下文的配置了。
修改你的代码示例如下:
describe MyClass do describe '#some_method' do # 把需要用共享上下文的测试放在这个子context里 context 'with standard setup' do include_context 'my shared context' # 原来使用共享上下文的specs... it 'does something with shared context' do expect(subject.some_method).to eq(...) end end # 这个特殊context自然就不会加载共享上下文了 context 'with some special context' do # 你的特殊测试代码,不受共享上下文影响 it 'does something special without shared context' do expect(subject.some_method).to eq(...) end end end end
方法2:手动重置共享上下文带来的变更
如果没办法重构代码结构,你可以在特殊context里手动抵消共享上下文的影响——比如重置它定义的let变量、before钩子设置的状态,或者清除它创建的mock。
假设你的共享上下文是这样的:
RSpec.shared_context 'my shared context' do let(:dependency) { double('Dependency') } before { @config = :default } end
那在特殊context里可以这样重置:
describe MyClass do include_context 'my shared context' describe '#some_method' do # 使用共享上下文的specs... context 'with some special context' do # 重置let变量为你需要的特殊值(或者nil) let(:dependency) { nil } # 重置before钩子设置的实例变量 before { @config = :special } # 你的特殊测试代码 end end end
方法3:给共享上下文添加条件判断(备选方案)
如果你有权限修改共享上下文的代码,可以给它加上条件判断,通过metadata来控制是否生效。
修改共享上下文:
RSpec.shared_context 'my shared context' do # 只有当metadata里没有skip_shared_context时才生效 unless example.metadata[:skip_shared_context] let(:dependency) { double('Dependency') } before { @config = :default } end end
然后在需要禁用的context里添加metadata:
describe MyClass do include_context 'my shared context' describe '#some_method' do # 使用共享上下文的specs... context 'with some special context', skip_shared_context: true do # 这里共享上下文的内容不会生效 end end end
这个方法需要修改共享上下文,会增加它的复杂度,所以只推荐在没办法用前两种方法时使用。
内容的提问来源于stack exchange,提问作者Richard-Degenne
相关产品推荐
相关产品推荐

