我有以下方法
def post_it(data_hash)
uri = URI.parse("https://example.com/api")
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.path)
request.content_type = "application/json"
request.body = data_hash.to_json
response = http.request(request)
return {code: response.code, body: JSON.parse(response.body)}
end
我想用 RSpec 测试两件事: 1- 向预期的 uri 发出请求。 2- 请求是通过预期的主体提出的。
第一点已经讲完了
it "is posted to the expected endpoint" do
expect(Net::HTTP::Post).to receive(:new).with("/api")
Gateway.new.post_it({id: 123})
end
但是我找不到一种方法(不嘲笑一切,我不想这样做)来测试第二点。我尝试过使用 VCR,但在我看来我只能验证响应。
有什么想法吗?
尝试使用 WebMock。
此 gem 支持模拟 HTTP 请求,并在使用 请求回调 发出模拟 HTTP 请求后断言请求签名和响应。
我们在您的测试中是这样做的:
describe Gateway
let(:request_body) { { hello: 'world' } }
before do
# Test setup
# Make sure to return a JSON response body
# since your method is parsing the response
stub_request(:post, 'https://example.com/api')
.to_return(body: { message: 'Success!' }.to_json)
end
subject { described_class.new.post_it(request_body) }
context 'when client sends a request' do
it 'has the correct request signature' do
WebMock.after_request do |request|
expect(request.uri.path).to eq('/api')
expect(request.body).to eq(request_body.to_json)
end
subject
end
end
end