我monkeypatched URI并为它编写测试:
describe URI do
describe '.sanitize_domain' do
let(:expectation) { 'toolbar.google.com' }
subject { described_class.sanitize_domain(url) }
context 'when url is correct' do
context 'when url misses both http and www prefixes' do
let(:url) { 'toolbar.google.com/public' }
it { is_expected.to eq(expectation) }
end
context 'when url contains www' do
let(:url) { 'www.toolbar.google.com/public' }
it { is_expected.to eq(expectation) }
end
context 'when url contains https' do
let(:url) { 'https://toolbar.google.com/public' }
it { is_expected.to eq(expectation) }
end
context 'when url contains both http and www' do
let(:url) { 'http://www.toolbar.google.com/public' }
it { is_expected.to eq(expectation) }
end
context 'when multiple urls are given' do
let(:url) { 'http://www.toolbar.google.com/Default.asp, http://www.toolbar.google.com/' }
it { is_expected.to eq(expectation) }
end
end
end
end
如您所见,it { is_expected.to eq(expectation) }
在每个上下文中重复出现。
我认为有一种解决办法让它干涸一点。
我可以在这里使用shared_examples,但恕我直言,对单个it
执行此操作会有些过分,可读性会降低。
我尝试将expectation
提取到before(:context) { it { is_expected } }
,但it
块中没有before
关键字。以下是该尝试的错误消息:
it
在示例(例如it
块)中或在示例范围内运行的构造(例如before
,let
中不可用,等等)。它仅适用于示例组(例如describe
或context
块)。
答案 0 :(得分:1)
inner_contextes_urls = [
['when url misses both http and www prefixes', 'toolbar.google.com/public'],
['when url contains www', 'www.toolbar.google.com/public']
# ...
]
inner_contextes_urls.each do |(title, url)|
context "#{title}" do
let(:url) { "#{url}" }
it { is_expected.to eq(expectation) }
end
end
答案 1 :(得分:1)
对于最小和可读的测试,只需提取一个方法:
describe URI do
describe '.sanitize_domain' do
context 'when url is correct' do
it 'sanitizes a URL without http and www prefixes' do
expect_sanitized_domain_to_handle 'toolbar.google.com/public'
end
it 'sanitizes a URL which contains www' do
expect_sanitized_domain_to_handle 'www.toolbar.google.com/public'
end
it 'sanitizes a URL which contains https' do
expect_sanitized_domain_to_handle 'https://toolbar.google.com/public'
end
it 'sanitizes a URL which contains both http and www' do
expect_sanitized_domain_to_handle 'https://www.toolbar.google.com/public'
end
it 'sanitizes a string containing multiple URLs' do
expect_sanitized_domain_to_handle 'http://www.toolbar.google.com/Default.asp, http://www.toolbar.google.com/'
end
def expect_sanitized_domain_to_handle(url)
expect(URL.sanitize_domain(url)).to eq('toolbar.google.com')
end
end
end
end
或者,要将预期的返回值放入您可以看到它的测试中,并在需要具有不同返回值的测试时更改它:
it 'sanitizes a URL from a different site' do
expect_sanitized_domain given: 'http://stackoverflow.com/questions/32331374/the-same-test-case-for-few-contexts-in-rspec-how-to-dry-it',
to_return: 'stackoverflow.com'
end
def expect_sanitized_domain(given:, to_return:)
expect(URL.sanitize_domain(given)).to eq(to_return)
end