RSpec中WebMock to_raise未触发预期错误的问题求助
问题分析与修复方案
你的测试报错是因为两个核心问题:WebMock拦截了未匹配的请求,以及代码里的rescue块存在潜在的变量未定义错误。下面一步步帮你修正:
1. 修正WebMock的Stub URL匹配问题
你的Service.status方法会自动给传入的base_uri拼接/status,但测试里Stub的是原始的bad_url,导致实际请求的URL(http://bar_url.com/status)和Stub的URL不匹配。WebMock会拦截所有未注册的真实请求,所以抛出了它自己的NetConnectNotAllowedError,而不是你预设的StandardError。
修改测试用例:
it 'should return error msg if url is not valid' do bad_url = "http://bar_url.com" # 拼接上/status,和Service方法里的URL处理逻辑保持一致 stubbed_url = "#{bad_url}/status" expected = 'Error occured' stub_request(:get, stubbed_url). with(headers: {'Authorization'=>'Basic YWRtaW46YWRtaW4='}). to_raise(StandardError) expect { Service.status(bad_url, { username: @username, password: @password }) }.to raise_error(/#{ expected }/) end
2. 修复Rescue块中的变量未定义问题
如果HTTParty.get在执行时直接抛出异常(比如连接失败),response变量根本没被赋值,这时你在raise语句里引用response.code会触发新的NameError,导致测试逻辑被干扰。
修改Service类的rescue逻辑:
class Service def self.status(base_uri = 'localhost', basic_auth = {}) base_uri = "#{ base_uri }/status" response = HTTParty.get(base_uri, basic_auth: basic_auth) rescue StandardError => e # 用安全调用&.判断response是否存在,避免变量未定义错误 error_code = response&.code || 'N/A' raise "Error occured code: #{ error_code } msg: #{ e.message }" end end
修复原理
- 第一个修改让Stub的URL和实际请求的URL完全匹配,WebMock就会触发你预设的
StandardError,而不是拦截未注册请求。 - 第二个修改避免了在异常场景下引用未定义的
response变量,保证错误信息能正常抛出,让你的测试断言能正确捕获。
内容的提问来源于stack exchange,提问作者Mark
相关产品推荐
相关产品推荐

